summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--decoder.cpp49
-rw-r--r--decoder.h2
-rw-r--r--global.h3
-rw-r--r--markad-standalone.cpp76
-rw-r--r--markad-standalone.h1
-rw-r--r--queue.cpp2
-rw-r--r--streaminfo.cpp90
-rw-r--r--video.cpp13
8 files changed, 122 insertions, 114 deletions
diff --git a/decoder.cpp b/decoder.cpp
index ea0672e..a9fb7b4 100644
--- a/decoder.cpp
+++ b/decoder.cpp
@@ -126,8 +126,6 @@ cMarkAdDecoder::cMarkAdDecoder(int RecvNumber, bool useH264, bool useMP2, bool h
if (video_codec->capabilities & CODEC_CAP_TRUNCATED)
video_context->flags|=CODEC_FLAG_TRUNCATED; // we do not send complete frames
- video_context->flags|=CODEC_FLAG_EMU_EDGE; // now linesize should be the same as width
-
video_context->flags|=CODEC_FLAG_GRAY; // only decode grayscale
video_context->flags2|=CODEC_FLAG2_FAST; // really?
@@ -137,11 +135,11 @@ cMarkAdDecoder::cMarkAdDecoder(int RecvNumber, bool useH264, bool useMP2, bool h
{
video_context->flags2|=CODEC_FLAG2_CHUNKS; // needed for H264!
video_context->skip_loop_filter=AVDISCARD_ALL; // skip deblocking
- video_context->skip_frame=AVDISCARD_NONREF; // P/I-frames
+ av_log_set_level(AV_LOG_FATAL); // H264 decoder is very chatty
}
else
{
- video_context->skip_frame=AVDISCARD_NONKEY; // I-frames
+ video_context->skip_frame=AVDISCARD_NONKEY; // just I-frames
}
int ret=avcodec_open(video_context, video_codec);
@@ -171,6 +169,14 @@ cMarkAdDecoder::cMarkAdDecoder(int RecvNumber, bool useH264, bool useMP2, bool h
}
else
{
+
+ dsyslog("markad [%i]: using codec %s",recvnumber,video_codec->long_name);
+
+ if (video_context->hwaccel)
+ {
+ dsyslog("markad [%i]: using hwaccel %s",recvnumber,video_context->hwaccel->name);
+ }
+
video_frame = avcodec_alloc_frame();
if (!video_frame)
{
@@ -224,7 +230,6 @@ cMarkAdDecoder::~cMarkAdDecoder()
av_free(mp2_context);
}
if (audiobuf) free(audiobuf);
- SetVideoInfos(NULL,NULL,NULL,NULL);
}
bool cMarkAdDecoder::DecodeMP2(MarkAdContext *maContext, uchar *espkt, int eslen)
@@ -260,7 +265,7 @@ bool cMarkAdDecoder::DecodeMP2(MarkAdContext *maContext, uchar *espkt, int eslen
if (audiobufsize>0)
{
memcpy(audiobuf,Taudiobuf,audiobufsize);
- SetAudioInfos(maContext,ac3_context);
+ SetAudioInfos(maContext,mp2_context);
ret=true;
avpkt.size-=len;
avpkt.data+=len;
@@ -273,6 +278,7 @@ bool cMarkAdDecoder::SetAudioInfos(MarkAdContext *maContext, AVCodecContext *Aud
{
if ((!maContext) || (!Audio_Context)) return false;
+ maContext->Audio.Info.SampleRate = Audio_Context->sample_rate;
maContext->Audio.Info.Channels = Audio_Context->channels;
maContext->Audio.Data.SampleBuf=audiobuf;
maContext->Audio.Data.SampleBufLen=audiobufsize;
@@ -328,7 +334,7 @@ void cMarkAdDecoder::PAR2DAR(AVRational a, AVRational *erg)
video_context->height*a.den,1024*1024);
}
-bool cMarkAdDecoder::SetVideoInfos(MarkAdContext *maContext,AVCodecContext *Video_Context, AVFrame *Video_Frame, AVRational *DAR)
+bool cMarkAdDecoder::SetVideoInfos(MarkAdContext *maContext,AVCodecContext *Video_Context, AVFrame *Video_Frame)
{
if ((!maContext) || (!Video_Context) || (!Video_Frame)) return false;
maContext->Video.Data.Valid=false;
@@ -347,11 +353,11 @@ bool cMarkAdDecoder::SetVideoInfos(MarkAdContext *maContext,AVCodecContext *Vide
maContext->Video.Info.Pict_Type=Video_Context->coded_frame->pict_type;
}
- if (DAR)
- {
- maContext->Video.Info.AspectRatio.Num=DAR->num;
- maContext->Video.Info.AspectRatio.Den=DAR->den;
- }
+ AVRational dar;
+ PAR2DAR(Video_Context->sample_aspect_ratio,&dar);
+
+ maContext->Video.Info.AspectRatio.Num=dar.num;
+ maContext->Video.Info.AspectRatio.Den=dar.den;
maContext->Video.Data.Valid=true;
return true;
@@ -361,6 +367,21 @@ bool cMarkAdDecoder::DecodeVideo(MarkAdContext *maContext,uchar *pkt, int plen)
{
if (!video_context) return false;
+ if ((video_context->codec_id==CODEC_ID_H264) && (!video_context->skip_frame))
+ {
+ if (maContext->Video.Info.Pict_Type)
+ {
+ if (maContext->Video.Info.Interlaced)
+ {
+ video_context->skip_frame=AVDISCARD_BIDIR; // just P/I-frames
+ }
+ else
+ {
+ video_context->skip_frame=AVDISCARD_NONKEY; // just I-frames
+ }
+ }
+ }
+
AVPacket avpkt;
#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(25<<8)+0)
av_init_packet(&avpkt);
@@ -399,9 +420,7 @@ bool cMarkAdDecoder::DecodeVideo(MarkAdContext *maContext,uchar *pkt, int plen)
{
if (last_qscale_table!=video_frame->qscale_table)
{
- AVRational dar;
- PAR2DAR(video_context->sample_aspect_ratio,&dar);
- if (SetVideoInfos(maContext,video_context,video_frame,&dar)) ret=true;
+ if (SetVideoInfos(maContext,video_context,video_frame)) ret=true;
last_qscale_table=video_frame->qscale_table;
}
}
diff --git a/decoder.h b/decoder.h
index c14a48f..7a0d4e2 100644
--- a/decoder.h
+++ b/decoder.h
@@ -56,7 +56,7 @@ private:
void PAR2DAR(AVRational a, AVRational *erg);
bool SetVideoInfos(MarkAdContext *maContext,AVCodecContext *Video_Context,
- AVFrame *Video_Frame, AVRational *DAR);
+ AVFrame *Video_Frame);
public:
bool DecodeVideo(MarkAdContext *maContext, uchar *pkt, int plen);
bool DecodeMP2(MarkAdContext *maContext, uchar *espkt, int eslen);
diff --git a/global.h b/global.h
index 189613c..ec74501 100644
--- a/global.h
+++ b/global.h
@@ -56,6 +56,7 @@ typedef struct MarkAdContext
int LogoExtraction;
int LogoWidth;
int LogoHeight;
+ MarkAdAspectRatio AspectRatioHint;
} StandAlone;
struct General
@@ -75,6 +76,7 @@ typedef struct MarkAdContext
int Pict_Type; // picture type (I,P,B,S,SI,SP,BI)
MarkAdAspectRatio AspectRatio;
double FramesPerSecond;
+ bool Interlaced;
} Info;
struct Data
@@ -90,6 +92,7 @@ typedef struct MarkAdContext
struct Info
{
int Channels; // number of audio channels
+ int SampleRate;
} Info;
struct Data
{
diff --git a/markad-standalone.cpp b/markad-standalone.cpp
index 4d41ac5..8222920 100644
--- a/markad-standalone.cpp
+++ b/markad-standalone.cpp
@@ -15,6 +15,8 @@ char logoDirectory[1024]="";
int logoExtraction=-1;
int logoWidth=-1;
int logoHeight=-1;
+bool bDecodeVideo=true;
+bool bDecodeAudio=true;
void syslog_with_tid(int priority, const char *format, ...)
{
@@ -80,10 +82,12 @@ void cMarkAdStandalone::SaveFrame(int frame)
return;
// Write header
- fprintf(pFile, "P5\n%d %d\n255\n", macontext.Video.Info.Width,macontext.Video.Info.Height);
+ fprintf(pFile, "P5\n%d %d\n255\n", macontext.Video.Data.PlaneLinesize[0],
+ macontext.Video.Info.Height);
// Write pixel data
- fwrite(macontext.Video.Data.Plane[0],1,macontext.Video.Info.Width*macontext.Video.Info.Height,pFile);
+ fwrite(macontext.Video.Data.Plane[0],1,
+ macontext.Video.Data.PlaneLinesize[0]*macontext.Video.Info.Height,pFile);
// Close file
fclose(pFile);
}
@@ -118,7 +122,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
if (abort) break;
MarkAdMark *mark=NULL;
- if ((video_demux) && (video) && (decoder) && (streaminfo))
+ if ((video_demux) && (video) && (streaminfo))
{
uchar *pkt;
int pktlen;
@@ -143,11 +147,13 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
framecnt++;
}
- if (decoder->DecodeVideo(&macontext,pkt,pktlen))
+ bool dRes=true;
+ if ((decoder) && (bDecodeVideo)) dRes=decoder->DecodeVideo(&macontext,pkt,pktlen);
+ if (dRes)
{
if (macontext.Video.Info.Pict_Type==MA_I_TYPE)
{
- if (macontext.General.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264)
+ if ((macontext.General.VPid.Type==MARKAD_PIDTYPE_VIDEO_H264) || (!bDecodeVideo))
{
lastiframe=framecnt-1;
}
@@ -155,7 +161,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
{
lastiframe=framecnt-2;
}
- // SaveFrame(lastiframe); // TODO: JUST FOR DEBUGGING!
+ //SaveFrame(lastiframe); // TODO: JUST FOR DEBUGGING!
mark=video->Process(lastiframe);
AddMark(mark);
}
@@ -208,7 +214,7 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
}
}
- if ((mp2_demux) && (decoder) && (audio))
+ if ((mp2_demux) && (decoder) && (audio) && (bDecodeAudio))
{
uchar *pkt;
int pktlen;
@@ -252,6 +258,12 @@ bool cMarkAdStandalone::ProcessFile(const char *Directory, int Number)
void cMarkAdStandalone::Process(const char *Directory)
{
if (abort) return;
+
+ struct timeval tv1,tv2;
+ struct timezone tz;
+
+ gettimeofday(&tv1,&tz);
+
for (int i=1; i<=MaxFiles; i++)
{
if (abort) break;
@@ -264,6 +276,25 @@ void cMarkAdStandalone::Process(const char *Directory)
{
isyslog("markad [%i]: aborted",recvnumber);
}
+ else
+ {
+ gettimeofday(&tv2,&tz);
+ long sec,usec;
+ sec=tv2.tv_sec-tv1.tv_sec;
+ usec=tv2.tv_usec-tv1.tv_usec;
+ if (usec<0)
+ {
+ usec+=1000000;
+ sec--;
+ }
+ double etime,ftime=0,ptime=0;
+ etime=sec+((double) usec/1000000);
+ if (etime>0) ftime=framecnt/etime;
+ if (macontext.Video.Info.FramesPerSecond>0)
+ ptime=ftime/macontext.Video.Info.FramesPerSecond;
+ isyslog("markad [%i]: elapsed time %.2fs, %i frames, %.1f fps, %.1f pps",recvnumber,
+ etime,framecnt,ftime,ptime);
+ }
}
bool cMarkAdStandalone::LoadInfo(const char *Directory)
@@ -485,6 +516,7 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory)
}
else
{
+ macontext.General.APid.Num=-1;
macontext.General.DPid.Num=-1;
macontext.General.VPid.Num=-1;
macontext.General.VPid.Type=MARKAD_PIDTYPE_VIDEO_H262;
@@ -588,6 +620,9 @@ int usage()
"-b --background\n"
" markad runs as a background-process\n"
" this will be automatically set if called with \"after\"\n"
+ "-d --disable=<option>\n"
+ " <option> 1 = disable video 2 = disable audio\n"
+ " 3 = disable video and audio\n"
"-l --logocachedir\n"
" directory where logos stored, default /var/lib/markad\n"
"-p, --priority level=<priority>\n"
@@ -608,8 +643,8 @@ int usage()
" markad sends an OSD-Message for start and end\n"
"-V --version\n"
" print version-info and exit\n"
- "--markfile=<markfilename>\n"
- " set a different markfile-name\n"
+ " --markfile=<markfilename>\n"
+ " set a different markfile-name\n"
"\ncmd: one of\n"
"- dummy-parameter if called directly\n"
"after markad starts to analyze the recording\n"
@@ -656,6 +691,7 @@ int main(int argc, char *argv[])
{
{"statisticfile",1,0,'s'
},
+ {"disable", 1, 0, 'd'},
{"logocachedir", 1, 0, 'l'},
{"extractlogo", 1, 0, 'L'},
{"verbose", 0, 0, 'v'},
@@ -681,7 +717,7 @@ int main(int argc, char *argv[])
{0, 0, 0, 0}
};
- c = getopt_long (argc, argv, "s:l:vbp:cjoaOSBCVL:",
+ c = getopt_long (argc, argv, "s:l:vbp:cjoaOSBCVL:d:",
long_options, &option_index);
if (c == -1)
break;
@@ -694,6 +730,26 @@ int main(int argc, char *argv[])
if (SysLogLevel>10) SysLogLevel=10;
break;
+ case 'd':
+ switch (atoi(optarg))
+ {
+ case 1:
+ bDecodeVideo=false;
+ break;
+ case 2:
+ bDecodeAudio=false;
+ break;
+ case 3:
+ bDecodeVideo=false;
+ bDecodeAudio=false;
+ break;
+ default:
+ fprintf(stderr, "markad: invalid disable option: %s\n", optarg);
+ return 2;
+ break;
+ }
+ break;
+
case 'b':
bFork = true;
break;
diff --git a/markad-standalone.h b/markad-standalone.h
index 3323fec..8edf655 100644
--- a/markad-standalone.h
+++ b/markad-standalone.h
@@ -17,6 +17,7 @@
#include <getopt.h>
#include <signal.h>
#include <ctype.h>
+#include <sys/time.h>
#include "demux.h"
#include "global.h"
diff --git a/queue.cpp b/queue.cpp
index f5f158e..5465168 100644
--- a/queue.cpp
+++ b/queue.cpp
@@ -205,7 +205,7 @@ int cMarkAdPaketQueue::FindAudioHeader(int Start, int *FrameSize, int *HeaderSiz
scanner|=buffer[i];
}
if (i==inptr) return -1;
- i-=2;
+ if (AC3) i-=2;
if (AC3)
{
diff --git a/streaminfo.cpp b/streaminfo.cpp
index bad7a0e..30deea5 100644
--- a/streaminfo.cpp
+++ b/streaminfo.cpp
@@ -7,7 +7,7 @@
*/
#include "streaminfo.h"
-
+#include <stdio.h>
cMarkAdStreamInfo::cMarkAdStreamInfo()
{
memset(&H264,0,sizeof(H264));
@@ -236,8 +236,10 @@ bool cMarkAdStreamInfo::FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt,
num_units_in_tick = bs.getU32(); // num_units_in_tick
time_scale = bs.getU32(); // time_scale
if (num_units_in_tick > 0)
+ {
frame_rate = time_scale / (2*num_units_in_tick);
-
+ if (H264.frame_mbs_only_flag) frame_rate/=2;
+ }
//bs.skipBit(); // fixed_frame_rate_flag
}
/*
@@ -409,8 +411,11 @@ bool cMarkAdStreamInfo::FindH264VideoInfos(MarkAdContext *maContext, uchar *pkt,
bs.skipBits(2); // colour_plane_id
}
bs.skipBits(H264.log2_max_frame_num); // frame_num
+
+ maContext->Video.Info.Interlaced=false;
if (!H264.frame_mbs_only_flag)
{
+ maContext->Video.Info.Interlaced=true;
bool field_pic_flag=bs.getBit();
if (field_pic_flag)
{
@@ -612,87 +617,6 @@ unsigned TemporalReferenceL:
return false;
}
-/*
-// taken from ffmpeg
-int cMarkAdStreamInfo::nalUnescape(uint8_t *dst, const uint8_t *src, int length)
-{
- int i;
-
-#if HAVE_FAST_UNALIGNED
-# if HAVE_FAST_64BIT
-# define RS 7
- for (i=0; i+1<length; i+=9)
- {
- if (!((~*(const uint64_t*)(src+i) & (*(const uint64_t*)(src+i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL))
-# else
-# define RS 3
- for (i=0; i+1<length; i+=5)
- {
- if (!((~*(const uint32_t*)(src+i) & (*(const uint32_t*)(src+i) - 0x01000101U)) & 0x80008080U))
-# endif
- continue;
- if (i>0 && !src[i]) i--;
- while (src[i]) i++;
-#else
-# define RS 0
- for (i=0; i+1<length; i+=2)
- {
- if (src[i]) continue;
- if (i>0 && src[i-1]==0) i--;
-#endif
- if (i+2<length && src[i+1]==0 && src[i+2]<=3)
- {
- if (src[i+2]!=3)
- {
- // startcode, so we must be past the end
- length=i;
- }
- break;
- }
- i-= RS;
- }
-
- memcpy(dst,src,i);
-
- if (i>=length-1) //no escaped 0
- {
- return length;
- }
-
- int si,di;
- si=di=i;
- while (si+2<length)
- {
- //remove escapes (very rare 1:2^22)
- if (src[si+2]>3)
- {
- dst[di++]= src[si++];
- dst[di++]= src[si++];
- }
- else if (src[si]==0 && src[si+1]==0)
- {
- if (src[si+2]==3) //escape
- {
- dst[di++]= 0;
- dst[di++]= 0;
- si+=3;
- continue;
- }
- else //next start code
- goto nsc;
- }
-
- dst[di++]= src[si++];
- }
- while (si<length)
- dst[di++]= src[si++];
-nsc:
-
- return di;
-}
-*/
-
-
// taken from femon
int cMarkAdStreamInfo::nalUnescape(uint8_t *dst, const uint8_t *src, int len)
{
diff --git a/video.cpp b/video.cpp
index 8a61afe..122c346 100644
--- a/video.cpp
+++ b/video.cpp
@@ -165,10 +165,12 @@ int cMarkAdLogo::Detect(int lastiframe, int *logoiframe)
{
for (int X=xstart; X<=xend-1; X++)
{
- area.source[(X-xstart)+(Y-ystart)*LOGOWIDTH]=macontext->Video.Data.Plane[0][X+(Y*macontext->Video.Info.Width)];
+ area.source[(X-xstart)+(Y-ystart)*LOGOWIDTH]=
+ macontext->Video.Data.Plane[0][X+(Y*macontext->Video.Data.PlaneLinesize[0])];
SUMA+=area.source[(X-xstart)+(Y-ystart)*LOGOWIDTH];
}
}
+
SUMA/=(LOGOWIDTH*LOGOHEIGHT);
#if 0
if (SUMA>=100)
@@ -222,7 +224,8 @@ int cMarkAdLogo::Detect(int lastiframe, int *logoiframe)
for (int J=-1; J<=1; J++)
{
sumX=sumX+ (int) ((*(macontext->Video.Data.Plane[0]+X+I+
- (Y+J)*macontext->Video.Info.Width))*GX[I+1][J+1]);
+ (Y+J)*macontext->Video.Data.PlaneLinesize[0]))
+ *GX[I+1][J+1]);
}
}
@@ -232,7 +235,8 @@ int cMarkAdLogo::Detect(int lastiframe, int *logoiframe)
for (int J=-1; J<=1; J++)
{
sumY=sumY+ (int) ((*(macontext->Video.Data.Plane[0]+X+I+
- (Y+J)*macontext->Video.Info.Width))*GY[I+1][J+1]);
+ (Y+J)*macontext->Video.Data.PlaneLinesize[0]))*
+ GY[I+1][J+1]);
}
}
@@ -247,7 +251,8 @@ int cMarkAdLogo::Detect(int lastiframe, int *logoiframe)
area.sobel[(X-xstart)+(Y-ystart)*LOGOWIDTH]=val;
- area.result[(X-xstart)+(Y-ystart)*LOGOWIDTH]=(area.mask[(X-xstart)+(Y-ystart)*LOGOWIDTH] + val) & 255;
+ area.result[(X-xstart)+(Y-ystart)*LOGOWIDTH]=
+ (area.mask[(X-xstart)+(Y-ystart)*LOGOWIDTH] + val) & 255;
if (!area.result[(X-xstart)+(Y-ystart)*LOGOWIDTH]) area.rpixel++;