summaryrefslogtreecommitdiff
path: root/decoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'decoder.cpp')
-rw-r--r--decoder.cpp478
1 files changed, 0 insertions, 478 deletions
diff --git a/decoder.cpp b/decoder.cpp
deleted file mode 100644
index 6b01404..0000000
--- a/decoder.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * decoder.cpp: A program for the Video Disk Recorder
- *
- * See the README file for copyright information and how to reach the author.
- *
- */
-
-#include "decoder.h"
-
-cMarkAdDecoder::cMarkAdDecoder(bool useH264, bool useMP2, bool hasAC3)
-{
- avcodec_init();
- avcodec_register_all();
-
- last_qscale_table=NULL;
-
- cpu_set_t cpumask;
- uint len = sizeof(cpumask);
- int cpucount;
- if (sched_getaffinity(0,len,&cpumask)<0)
- {
- cpucount=1;
- }
- else
- {
- cpucount=CPU_COUNT(&cpumask);
- }
-
- int ver = avcodec_version();
- char libver[256];
- snprintf(libver,sizeof(libver),"%i.%i.%i",ver >> 16 & 0xFF,ver >> 8 & 0xFF,ver & 0xFF);
- isyslog("using libavcodec.so.%s with %i threads",libver,cpucount);
-
- if (ver!=LIBAVCODEC_VERSION_INT)
- {
- esyslog("libavcodec header version %s",AV_STRINGIFY(LIBAVCODEC_VERSION));
- esyslog("header and library mismatch, decoding disabled");
- video_context=NULL;
- ac3_context=NULL;
- mp2_context=NULL;
- audiobuf=NULL;
- return;
- }
-
- if (((ver >> 16)<52) && (useH264))
- {
- esyslog("dont report bugs about H264, use libavcodec >= 52 instead!");
- }
-
- if (useMP2)
- {
- CodecID mp2_codecid=CODEC_ID_MP2;
- AVCodec *mp2_codec= avcodec_find_decoder(mp2_codecid);
- if (mp2_codec)
- {
- mp2_context = avcodec_alloc_context();
- if (mp2_context)
- {
- mp2_context->thread_count=cpucount;
- mp2_context->codec_id = mp2_codecid;
- mp2_context->codec_type = CODEC_TYPE_AUDIO;
- if (avcodec_open(mp2_context, mp2_codec) < 0)
- {
- esyslog("could not open codec for MP2");
- av_free(mp2_context);
- mp2_context=NULL;
- }
- }
- else
- {
- esyslog("could not allocate mp2 context");
- }
- }
- else
- {
- esyslog("codec for MP2 not found");
- mp2_context=NULL;
- }
- }
- else
- {
- mp2_context=NULL;
- }
-
- if (hasAC3)
- {
- CodecID ac3_codecid=CODEC_ID_AC3;
- AVCodec *ac3_codec= avcodec_find_decoder(ac3_codecid);
- if (ac3_codec)
- {
- ac3_context = avcodec_alloc_context();
- if (ac3_context)
- {
- ac3_context->thread_count=cpucount;
- ac3_context->codec_id = ac3_codecid;
- ac3_context->codec_type = CODEC_TYPE_AUDIO;
- if (avcodec_open(ac3_context, ac3_codec) < 0)
- {
- esyslog("could not open codec for AC3");
- av_free(ac3_context);
- ac3_context=NULL;
- }
- }
- else
- {
- esyslog("could not allocate ac3 context");
- }
- }
- else
- {
- esyslog("codec for AC3 not found");
- ac3_context=NULL;
- }
- }
- else
- {
- ac3_context=NULL;
- }
-
- AVCodec *video_codec=NULL;
- CodecID video_codecid;
-
- if (useH264)
- {
- video_codecid=CODEC_ID_H264;
- }
- else
- {
- video_codecid=CODEC_ID_MPEG2VIDEO_XVMC;
- }
-
- video_codec = avcodec_find_decoder(video_codecid);
- if ((!video_codec) && (video_codecid==CODEC_ID_MPEG2VIDEO_XVMC))
- {
- // fallback to MPEG2VIDEO
- video_codecid=CODEC_ID_MPEG2VIDEO;
- video_codec=avcodec_find_decoder(video_codecid);
- }
-
- if (video_codec)
- {
- video_context = avcodec_alloc_context();
- if (video_context)
- {
- video_context->thread_count=cpucount;
- if (video_codec->capabilities & CODEC_CAP_TRUNCATED)
- video_context->flags|=CODEC_FLAG_TRUNCATED; // we do not send complete frames
-
- video_context->flags|=CODEC_FLAG_GRAY; // only decode grayscale
- video_context->flags2|=CODEC_FLAG2_FAST; // really?
-
- video_context->skip_idct=AVDISCARD_ALL;
-
- if (video_codecid==CODEC_ID_H264)
- {
- video_context->flags2|=CODEC_FLAG2_CHUNKS; // needed for H264!
- video_context->skip_loop_filter=AVDISCARD_ALL; // skip deblocking
- av_log_set_level(AV_LOG_FATAL); // H264 decoder is very chatty
- }
- else
- {
- video_context->skip_frame=AVDISCARD_NONKEY; // just I-frames
- }
-
- video_context->codec_id = video_codecid;
- video_context->codec_type = CODEC_TYPE_VIDEO;
- int ret=avcodec_open(video_context, video_codec);
- if ((ret < 0) && (video_codecid==CODEC_ID_MPEG2VIDEO_XVMC))
- {
- // fallback to MPEG2VIDEO
- video_codecid=CODEC_ID_MPEG2VIDEO;
- video_codec=avcodec_find_decoder(video_codecid);
- if (video_codec)
- {
- video_context->codec_type=CODEC_TYPE_UNKNOWN;
- video_context->codec_id=CODEC_ID_NONE;
- video_context->codec_tag=0;
- memset(video_context->codec_name,0,sizeof(video_context->codec_name));
- ret=avcodec_open(video_context, video_codec);
- }
- else
- {
- ret=-1;
- }
- }
- if (ret < 0)
- {
- switch (video_codecid)
- {
- case CODEC_ID_H264:
- esyslog("could not open codec for H264");
- break;
- case CODEC_ID_MPEG2VIDEO_XVMC:
- esyslog("could not open codec MPEG2 (XVMC)");
- break;
- case CODEC_ID_MPEG2VIDEO:
- esyslog("could not open codec MPEG2");
- break;
- default:
- esyslog("could not open video codec");
- break;
- }
- av_free(video_context);
- video_context=NULL;
- }
- else
- {
- isyslog("using codec %s",video_codec->long_name);
-
-#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(22<<8)+2)
- if (video_context->hwaccel)
- {
- isyslog("using hwaccel %s",video_context->hwaccel->name);
- }
-#endif
-
- video_frame = avcodec_alloc_frame();
- if (!video_frame)
- {
- esyslog("could not allocate frame");
- avcodec_close(video_context);
- av_free(video_context);
- video_context=NULL;
- }
- }
- }
- else
- {
- esyslog("could not allocate video context");
- }
- }
- else
- {
- switch (video_codecid)
- {
- case CODEC_ID_H264:
- esyslog("codec for H264 not found");
- break;
- case CODEC_ID_MPEG2VIDEO_XVMC:
- esyslog("codec for MPEG2 (XVMC) not found");
- break;
- case CODEC_ID_MPEG2VIDEO:
- esyslog("codec for MPEG2 not found");
- break;
- default:
- esyslog("video codec not found");
- break;
- }
- video_context=NULL;
- }
-
- if ((ac3_context) || (mp2_context))
- {
- audiobuf=(int16_t*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
- }
- else
- {
- audiobuf=NULL;
- }
-
-}
-
-cMarkAdDecoder::~cMarkAdDecoder()
-{
- if (video_context)
- {
- avcodec_close(video_context);
- av_free(video_context);
- av_free(video_frame);
- }
-
- if (ac3_context)
- {
- avcodec_close(ac3_context);
- av_free(ac3_context);
- }
-
- if (mp2_context)
- {
- avcodec_close(mp2_context);
- av_free(mp2_context);
- }
- if (audiobuf) free(audiobuf);
-}
-
-bool cMarkAdDecoder::DecodeMP2(MarkAdContext *maContext, uchar *espkt, int eslen)
-{
- if (!mp2_context) return false;
- maContext->Audio.Data.Valid=false;
- AVPacket avpkt;
-#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(25<<8)+0)
- av_init_packet(&avpkt);
-#else
- memset(&avpkt,0,sizeof(avpkt));
- avpkt.pts = avpkt.dts = AV_NOPTS_VALUE;
- avpkt.pos = -1;
-#endif
- avpkt.data=espkt;
- avpkt.size=eslen;
-
- audiobufsize=AVCODEC_MAX_AUDIO_FRAME_SIZE;
- int ret=false;
- int16_t Taudiobuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
- while (avpkt.size>0)
- {
-#if LIBAVCODEC_VERSION_INT < ((52<<16)+(25<<8)+0)
- int len=avcodec_decode_audio2(mp2_context,Taudiobuf,&audiobufsize,
- avpkt.data,avpkt.size);
-#else
- int len=avcodec_decode_audio3(mp2_context,Taudiobuf,&audiobufsize,&avpkt);
-#endif
- if (len<0)
- {
- esyslog("error decoding mp2");
- break;
- }
- if (audiobufsize>0)
- {
- memcpy(audiobuf,Taudiobuf,audiobufsize);
- SetAudioInfos(maContext,mp2_context);
- ret=true;
- avpkt.size-=len;
- avpkt.data+=len;
- }
- }
- return ret;
-}
-
-bool cMarkAdDecoder::SetAudioInfos(MarkAdContext *maContext, AVCodecContext *Audio_Context)
-{
- 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;
- maContext->Audio.Data.Valid=true;
- return true;
-}
-
-bool cMarkAdDecoder::DecodeAC3(MarkAdContext *maContext, uchar *espkt, int eslen)
-{
- if (!ac3_context) return false;
- maContext->Audio.Data.Valid=false;
- AVPacket avpkt;
-#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(25<<8)+0)
- av_init_packet(&avpkt);
-#else
- memset(&avpkt,0,sizeof(avpkt));
- avpkt.pts = avpkt.dts = AV_NOPTS_VALUE;
- avpkt.pos = -1;
-#endif
- avpkt.data=espkt;
- avpkt.size=eslen;
-
- int ret=false;
- int16_t Taudiobuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
- while (avpkt.size>0)
- {
- audiobufsize=AVCODEC_MAX_AUDIO_FRAME_SIZE;
-#if LIBAVCODEC_VERSION_INT < ((52<<16)+(25<<8)+0)
- int len=avcodec_decode_audio2(ac3_context,Taudiobuf,&audiobufsize,
- avpkt.data,avpkt.size);
-#else
- int len=avcodec_decode_audio3(ac3_context,Taudiobuf,&audiobufsize,&avpkt);
-#endif
- if (len<0)
- {
- esyslog("error decoding ac3");
- break;
- }
- if (audiobufsize>0)
- {
- memcpy(audiobuf,Taudiobuf,audiobufsize);
- SetAudioInfos(maContext,ac3_context);
- ret=true;
- avpkt.size-=len;
- avpkt.data+=len;
- }
- }
- return ret;
-}
-
-void cMarkAdDecoder::PAR2DAR(AVRational a, AVRational *erg)
-{
- av_reduce(&erg->num,&erg->den,video_context->width*a.num,
- video_context->height*a.den,1024*1024);
-}
-
-bool cMarkAdDecoder::SetVideoInfos(MarkAdContext *maContext,AVCodecContext *Video_Context, AVFrame *Video_Frame)
-{
- if ((!maContext) || (!Video_Context) || (!Video_Frame)) return false;
- for (int i=0; i<4; i++)
- {
- if (Video_Frame->data[i])
- {
- maContext->Video.Data.Plane[i]=Video_Frame->data[i];
- maContext->Video.Data.PlaneLinesize[i]=Video_Frame->linesize[i];
- maContext->Video.Data.Valid=true;
- }
- }
- maContext->Video.Info.Height=Video_Context->height;
- maContext->Video.Info.Width=Video_Context->width;
-
- AVRational dar;
- PAR2DAR(Video_Context->sample_aspect_ratio,&dar);
-
- maContext->Video.Info.AspectRatio.Num=dar.num;
- maContext->Video.Info.AspectRatio.Den=dar.den;
-
- return true;
-}
-
-bool cMarkAdDecoder::DecodeVideo(MarkAdContext *maContext,uchar *pkt, int plen)
-{
- if (!video_context) return false;
- maContext->Video.Data.Valid=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);
-#else
- memset(&avpkt,0,sizeof(avpkt));
- avpkt.pts = avpkt.dts = AV_NOPTS_VALUE;
- avpkt.pos = -1;
-#endif
- avpkt.data=pkt;
- avpkt.size=plen;
-
- // decode video
- int video_frame_ready=0;
- int len,ret=false;
-
- while (avpkt.size>0)
- {
-#if LIBAVCODEC_VERSION_INT < ((52<<16)+(25<<8)+0)
- len=avcodec_decode_video(video_context,video_frame,&video_frame_ready,
- avpkt.data,avpkt.size);
-#else
- len=avcodec_decode_video2(video_context,video_frame,&video_frame_ready,
- &avpkt);
-#endif
- if (len<0)
- {
- esyslog("error decoding video");
- break;
- }
- else
- {
- avpkt.size-=len;
- avpkt.data+=len;
- }
- if (video_frame_ready)
- {
- if (last_qscale_table!=video_frame->qscale_table)
- {
- if (SetVideoInfos(maContext,video_context,video_frame)) ret=true;
- last_qscale_table=video_frame->qscale_table;
- }
- }
- }
- return ret;
-}