From ad69b02279d893e0d2a54494d668b67d1dc384b9 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Tue, 6 Sep 2005 22:40:10 +0000 Subject: [PATCH] Widescreen support, segfault fix on livetv interrupt --- command.cc | 12 ++++++++ demuxer.cc | 21 ++++++++++++-- demuxer.h | 22 +++++++++----- message.h | 1 + playervideo.cc | 37 ++++++++++++++++++++--- video.cc | 13 +++++---- video.h | 1 + viewman.cc | 79 ++++++++++++++++++++++++++++---------------------- viewman.h | 1 + vvideolive.cc | 18 ++++++++++-- vvideolive.h | 3 ++ 11 files changed, 153 insertions(+), 55 deletions(-) diff --git a/command.cc b/command.cc index 4a6a6fb..1704831 100644 --- a/command.cc +++ b/command.cc @@ -56,6 +56,8 @@ int Command::init() return 0; } + logger->log("Command", Log::DEBUG, "%p", this); + return 1; } @@ -152,6 +154,16 @@ void Command::processMessage(Message* m) handleCommand(Remote::STOP); // an odd way of doing it, but so simple break; } + case Message::STREAM_END: + { + // post a message to ViewMan and then run the viewman message queue + Message* m = new Message(); + m->message = Message::STREAM_END; + m->to = VVideoLive::getInstance(); + viewman->postMessage(m); + handleCommand(Remote::NA_NONE); + break; + } case Message::VDR_CONNECTED: { doJustConnected((VConnect*)m->from); diff --git a/demuxer.cc b/demuxer.cc index 16fb793..8a2fbf9 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -29,6 +29,7 @@ Demuxer::Demuxer() if (instance) return; instance = this; initted = 0; + callback = NULL; } Demuxer::~Demuxer() @@ -42,7 +43,7 @@ Demuxer* Demuxer::getInstance() return instance; } -int Demuxer::init() +int Demuxer::init(Callback* tcallback) { if (!initted) { @@ -58,6 +59,7 @@ int Demuxer::init() reset(); initted = 1; + callback = tcallback; return 1; } @@ -67,7 +69,7 @@ void Demuxer::reset() video_current = audio_current = -1; horizontal_size = vertical_size = 0; aspect_ratio = (enum AspectRatio) 0; - frame_rate = bit_rate = 0; + cbAspectRatio = frame_rate = bit_rate = 0; } int Demuxer::shutdown() @@ -107,6 +109,20 @@ void Demuxer::setVideoStream(int id) video_current = id; } +void Demuxer::setAspectRatio() +{ + if (aspect_ratio != cbAspectRatio) + { + cbAspectRatio = aspect_ratio; + callback->call(this); + } +} + +int Demuxer::getAspectRatio() +{ + return aspect_ratio; +} + int Demuxer::scan(UCHAR *buf, int len) { // Temporarily, just look for the lowest audio stream and return it @@ -451,6 +467,7 @@ void Demuxer::parse_video_details(UCHAR* buf, int len) seeking = 0; buf += 8; // Minimum length of sequence header len -= 8; + setAspectRatio(); break; case 0xb8: // Group header // We're not going to bother parsing anything. diff --git a/demuxer.h b/demuxer.h index 6fe6368..c4bcfcb 100644 --- a/demuxer.h +++ b/demuxer.h @@ -35,6 +35,7 @@ however, no code was copied verbatim. #include "stream.h" #include "log.h" #include "defines.h" +#include "callback.h" class Demuxer { @@ -42,7 +43,7 @@ class Demuxer Demuxer(); ~Demuxer(); static Demuxer* getInstance(); - int init(); + int init(Callback* callback); void reset(); void flush(); void flushAudio(); @@ -54,6 +55,14 @@ class Demuxer int scan(UCHAR* buf, int len); int put(UCHAR* buf, int len); + int getAspectRatio(); + + enum AspectRatio + { + ASPECT_4_3 = 2, + ASPECT_16_9 = 3 + }; + private: static Demuxer* instance; Stream videostream; @@ -63,6 +72,9 @@ class Demuxer int seeking; UCHAR* inbuf; + void setAspectRatio(); + Callback* callback; + int video_current, audio_current; int state_frametype, state_framepos; int state_stream_fill, state_vid_parsed; @@ -134,17 +146,13 @@ class Demuxer FRAMETYPE_VIDMAX = FRAMETYPE_VID15 }; - enum AspectRatio - { - ASPECT_4_3 = 2, - ASPECT_16_9 = 3 - }; - int horizontal_size; int vertical_size; enum AspectRatio aspect_ratio; int frame_rate; int bit_rate; + + int cbAspectRatio; }; #endif diff --git a/message.h b/message.h index 190cfc4..e68c83e 100644 --- a/message.h +++ b/message.h @@ -53,6 +53,7 @@ class Message const static ULONG ADD_VIEW = 14; const static ULONG CHANNEL_UP = 15; const static ULONG CHANNEL_DOWN = 16; + const static ULONG STREAM_END = 17; }; #endif diff --git a/playervideo.cc b/playervideo.cc index 8bba1bf..aadf76e 100644 --- a/playervideo.cc +++ b/playervideo.cc @@ -47,7 +47,7 @@ int PlayerVideo::init() video = Video::getInstance(); - if (!demuxer.init()) + if (!demuxer.init(this)) { Log::getInstance()->log("Player", Log::ERR, "Demuxer failed to init"); shutdown(); @@ -490,7 +490,35 @@ void PlayerVideo::jumpToPercent(int percent) void PlayerVideo::call(void* caller) { - threadSignalNoLock(); + if (caller == &demuxer) + { + Log* temp = Log::getInstance(); + temp->log("Player", Log::DEBUG, "Callback from demuxer"); + if (video->getAspectRatio() == Video::ASPECT16X9) + { + temp->log("Player", Log::DEBUG, "TV is 16:9, so will try to do a switch"); + + int dxCurrentAspect = demuxer.getAspectRatio(); + if (dxCurrentAspect == Demuxer::ASPECT_4_3) + { + temp->log("Player", Log::DEBUG, "Demuxer said video is 4:3 aspect, switching TV"); + video->setMode(Video::LETTERBOX); // swap these lines over + } + else if (dxCurrentAspect == Demuxer::ASPECT_16_9) + { + temp->log("Player", Log::DEBUG, "Demuxer said video is 16:9 aspect, switching TV"); + video->setMode(Video::NORMAL); // if these are the wrong way around + } + else + { + temp->log("Player", Log::DEBUG, "Demuxer said video is something else... ignoring"); + } + } + } + else + { + threadSignalNoLock(); + } } // Feed thread @@ -602,8 +630,9 @@ void PlayerVideo::threadMethod() // end of recording Log::getInstance()->log("Player", Log::DEBUG, "Recording playback ends"); Message* m = new Message(); - m->message = Message::STOP_PLAYBACK; - Log::getInstance()->log("Player", Log::DEBUG, "Posting message..."); + if (streamLength) m->message = Message::STOP_PLAYBACK; // recording + else m->message = Message::STREAM_END; // live + Log::getInstance()->log("Player", Log::DEBUG, "Posting message to %p...", commandMessageQueue); commandMessageQueue->postMessage(m); Log::getInstance()->log("Player", Log::DEBUG, "Message posted..."); } diff --git a/video.cc b/video.cc index 576c554..32d0fa9 100644 --- a/video.cc +++ b/video.cc @@ -152,12 +152,10 @@ int Video::setMode(UCHAR tmode) && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0; mode = tmode; -// mode = LETTERBOX; + if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0; -// if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0; - - int a = ioctl(fdVideo, AV_SET_VID_MODE, mode); - printf("Mode requested: %i, result: %i\n", mode, a); +// int a = ioctl(fdVideo, AV_SET_VID_MODE, mode); +// printf("Mode requested: %i, result: %i\n", mode, a); return 1; } @@ -345,3 +343,8 @@ UINT Video::getScreenHeight() { return screenHeight; } + +UCHAR Video::getAspectRatio() +{ + return aspectRatio; +} diff --git a/video.h b/video.h index 29aa1a1..4ab987e 100644 --- a/video.h +++ b/video.h @@ -80,6 +80,7 @@ class Video int setFormat(UCHAR format); int setConnection(UCHAR connection); int setAspectRatio(UCHAR aspectRatio); + UCHAR getAspectRatio(); int setMode(UCHAR mode); int setSource(); int setPosition(int x, int y); diff --git a/viewman.cc b/viewman.cc index 7748681..70a3654 100644 --- a/viewman.cc +++ b/viewman.cc @@ -285,48 +285,57 @@ int ViewMan::handleCommand(UCHAR command) int retVal2 = 0; int i; - // handle command return values - // 0 - drop through to next view - // 1 - dont drop to next view, but not handled - // 2 - handled - stop command here - // 4 - handled - delete this view - - for (i=topView; i>0; i--) + if (command != Remote::NA_NONE) { - retVal = views[i]->handleCommand(command); - if (retVal == 1) - { - // not handled but don't give to any more views - pthread_mutex_unlock(&viewManLock); - return 0; - } - if (retVal == 2) + // handle command return values + // 0 - drop through to next view + // 1 - dont drop to next view, but not handled + // 2 - handled - stop command here + // 4 - handled - delete this view + + for (i=topView; i>0; i--) { - // command handled - if (views[i]->seconds) + retVal = views[i]->handleCommand(command); + if (retVal == 1) { - struct timespec currentTime; - clock_gettime(CLOCK_REALTIME, ¤tTime); - views[i]->delSec = currentTime.tv_sec + views[i]->seconds; - views[i]->delNSec = currentTime.tv_nsec; - resetThread(); + // not handled but don't give to any more views + pthread_mutex_unlock(&viewManLock); + return 0; + } + + if (retVal == 2) + { + // command handled + if (views[i]->seconds) + { + struct timespec currentTime; + clock_gettime(CLOCK_REALTIME, ¤tTime); + views[i]->delSec = currentTime.tv_sec + views[i]->seconds; + views[i]->delNSec = currentTime.tv_nsec; + resetThread(); + } + pthread_mutex_unlock(&viewManLock); + retVal2 = 1; + break; + } + else if (retVal == 4) + { + // removeNoLock(views[i]); + // Box::showAll(); + // resetThread(); + removeView(views[i], 1); + pthread_mutex_unlock(&viewManLock); + retVal2 = 1; + break; } - pthread_mutex_unlock(&viewManLock); - retVal2 = 1; - break; - } - else if (retVal == 4) - { -// removeNoLock(views[i]); -// Box::showAll(); -// resetThread(); - removeView(views[i], 1); - pthread_mutex_unlock(&viewManLock); - retVal2 = 1; - break; } } + else + { + // fake the return code + retVal2 = 2; + } Log::getInstance()->log("ViewMan", Log::DEBUG, "out of handlecommand code, now on to messages"); diff --git a/viewman.h b/viewman.h index a742d51..bd0eb7e 100644 --- a/viewman.h +++ b/viewman.h @@ -30,6 +30,7 @@ #include "view.h" #include "message.h" #include "messagequeue.h" +#include "remote.h" class ViewMan : public MessageQueue { diff --git a/vvideolive.cc b/vvideolive.cc index 1e5f43b..93595d5 100644 --- a/vvideolive.cc +++ b/vvideolive.cc @@ -20,8 +20,11 @@ #include "vvideolive.h" +VVideoLive* VVideoLive::instance = NULL; + VVideoLive::VVideoLive(ChannelList* tchanList, ULONG tstreamType) { + instance = this; vdr = VDR::getInstance(); viewman = ViewMan::getInstance(); chanList = tchanList; @@ -31,7 +34,7 @@ VVideoLive::VVideoLive(ChannelList* tchanList, ULONG tstreamType) streamType = tstreamType; if (streamType == VDR::VIDEO) { - player = new PlayerVideo(NULL, 0); + player = new PlayerVideo(Command::getInstance(), 0); } else { @@ -48,6 +51,12 @@ VVideoLive::VVideoLive(ChannelList* tchanList, ULONG tstreamType) VVideoLive::~VVideoLive() { delete player; + instance = NULL; +} + +VVideoLive* VVideoLive::getInstance() +{ + return instance; } void VVideoLive::draw() @@ -142,7 +151,12 @@ void VVideoLive::processMessage(Message* m) vlb->draw(); vlb->show(); } - + else if (m->message == Message::STREAM_END) + { + Log::getInstance()->log("VVideoLive", Log::DEBUG, "streamEnd"); + stop(); + play(1); + } } void VVideoLive::doBanner() diff --git a/vvideolive.h b/vvideolive.h index 6925fe8..2c72efe 100644 --- a/vvideolive.h +++ b/vvideolive.h @@ -35,12 +35,14 @@ #include "colour.h" #include "osd.h" #include "vinfo.h" +#include "command.h" class VVideoLive : public View { public: VVideoLive(ChannelList* chanList, ULONG streamType); ~VVideoLive(); + static VVideoLive* getInstance(); void draw(); int handleCommand(int command); void processMessage(Message* m); @@ -51,6 +53,7 @@ class VVideoLive : public View void stop(int noRemoveVLB = 0); private: + static VVideoLive* instance; ViewMan* viewman; VDR* vdr; Player* player; -- 2.39.2