From 1b20a29b33e83e672f8bc0a7c3c52405d663a44f Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sat, 17 Nov 2012 14:45:02 +0100 Subject: [PATCH] Let vomp handle aspect ratio change, better aspect ratio control for HD and SD --- demuxer.cc | 46 ++++++++++++++++++++++++++++++++++++++++++---- demuxer.h | 11 ++++++++--- player.cc | 10 ++++++---- playerlivetv.cc | 10 ++++++---- playermedia.cc | 13 ++++++++----- video.cc | 2 ++ video.h | 3 ++- videomvp.cc | 12 +++++++----- videomvp.h | 2 +- videoomx.cc | 36 +++++++++++++++++++++++++++++++----- videoomx.h | 2 +- videowin.cc | 6 ++++-- videowin.h | 2 +- 13 files changed, 119 insertions(+), 36 deletions(-) diff --git a/demuxer.cc b/demuxer.cc index db37c9d..c9f27b8 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -475,6 +475,8 @@ void Demuxer::reset() horizontal_size = vertical_size = 0; interlaced=true; // default is true aspect_ratio = (enum AspectRatio) 0; + parx=1; + pary=1; frame_rate = bit_rate = 0; ispre_1_3_19 = false; h264 = false; @@ -544,7 +546,7 @@ void Demuxer::setDVBSubtitleStream(int id) subtitle_current = id; } -void Demuxer::setAspectRatio(enum AspectRatio ar) +void Demuxer::setAspectRatio(enum AspectRatio ar, int taspectx, int taspecty) { if (aspect_ratio != ar) { @@ -554,6 +556,8 @@ void Demuxer::setAspectRatio(enum AspectRatio ar) { arcnt = 0; aspect_ratio = ar; + parx=taspectx; + pary=taspecty; if (callback) callback->call(this); } } @@ -782,7 +786,32 @@ pre_1_3_19_Recording: //This is for old recordings stuff and live TV vertical_size = (((int)packet[pos+1] & 0xf) << 8) | (int)packet[pos+2]; - setAspectRatio((enum AspectRatio)(packet[pos+3] >> 4)); + enum AspectRatio aspect=(enum AspectRatio)(packet[pos+3] >> 4); + int aspectx=1; + int aspecty=1; + const int aspectDAR[]={0,1,1,1,4,3,16,9,221,100}; + int aspectDARx=aspectDAR[aspect*2]; + int aspectDARy=aspectDAR[aspect*2+1]; + + aspectx=aspectDARx*vertical_size; + aspecty=aspectDARy*horizontal_size; + + int commona; + int commonb; + // Log::getInstance()->log("Demuxer", Log::DEBUG, "PAR test1 %d %d %d %d ", aspectx,aspecty,commona,commonb); + commona=aspectx; + commonb=aspecty; + + while (commonb) { + int temp=commonb; + commonb=commona%commonb; + commona=temp; + } + aspectx=aspectx/commona; + aspecty=aspecty/commona; + //Log::getInstance()->log("Demuxer", Log::DEBUG, "PAR test2 %d %d %d %d %d %d %d", aspectx,aspecty,aspectDARx,aspectDARy,horizontal_size,vertical_size,commona); + + setAspectRatio(aspect,aspectx,aspecty); frame_rate = packet[pos+3] & 0x0f; if (frame_rate >= 1 && frame_rate <= 8) frame_rate = FrameRates[frame_rate]; @@ -894,14 +923,20 @@ pre_1_3_19_Recording: //This is for old recordings stuff and live TV { UINT aspectratioidc=nalu.getBits(8); bool hasaspect=false; + int aspectx,aspecty; const float aspects[]={1., 1./1.,12./11.,10./11.,16./11.,40./33., 24./11.,20./11.,32./11.,80./33.,18./11.,15./11.,64./33.,160./99.,4./3.,3./2.,2./1.}; + const int aspectsx[]={1, 1,12,10,16,40, + 24,20,32,80,18,15,64,160,4,3,2}; + const int aspectsy[]={1, 1,11,11,11,33,11,11,11,33,11,11,33,99,3,2,1}; float aspectratio=((float) horizontal_size)/((float) vertical_size); if (aspectratioidc<=16) { hasaspect=true; aspectratio*=aspects[aspectratioidc]; + aspectx=aspectsx[aspectratioidc]; + aspecty=aspectsy[aspectratioidc]; } else if (aspectratioidc==255) @@ -912,12 +947,15 @@ pre_1_3_19_Recording: //This is for old recordings stuff and live TV { hasaspect=true; aspectratio*=((float)t_sar_width)/((float)t_sar_height); + aspectx=t_sar_width; + aspecty=t_sar_height; } } if (hasaspect) { - if (fabs(aspectratio-16./9.)<0.1) setAspectRatio(ASPECT_16_9); - else if (fabs(aspectratio-4./3.)<0.1) setAspectRatio(ASPECT_4_3); + if (fabs(aspectratio-16./9.)<0.1) setAspectRatio(ASPECT_16_9,aspectx,aspecty); + else if (fabs(aspectratio-4./3.)<0.1) setAspectRatio(ASPECT_4_3,aspectx,aspecty); + else setAspectRatio(ASPECT_1_1,aspectx,aspecty); } } diff --git a/demuxer.h b/demuxer.h index 54db93c..d34612b 100644 --- a/demuxer.h +++ b/demuxer.h @@ -120,7 +120,8 @@ class Demuxer int getHorizontalSize() { return horizontal_size; } int getVerticalSize() { return vertical_size; } - int getAspectRatio() { return aspect_ratio; } + int getAspectRatio(int *tparx,int *tpary) { + *tparx=parx; *tpary=pary;return aspect_ratio; } int getFrameRate() { return frame_rate; } int getBitRate() { return bit_rate; } bool getInterlaced() { return interlaced;} @@ -129,8 +130,10 @@ class Demuxer enum AspectRatio { + ASPECT_1_1 = 1, ASPECT_4_3 = 2, - ASPECT_16_9 = 3 + ASPECT_16_9 = 3, + ASPECT_221 = 4, }; // Remove all data from a buffer apart from video PES packets. @@ -207,7 +210,9 @@ class Demuxer int astreamtype; // Video stream information - void setAspectRatio(enum AspectRatio); + void setAspectRatio(enum AspectRatio, int taspectx, int taspecty); + int parx; + int pary; Callback* callback; int horizontal_size; diff --git a/player.cc b/player.cc index c8f9329..091fb0a 100644 --- a/player.cc +++ b/player.cc @@ -974,11 +974,12 @@ void Player::call(void* caller) return; } - int dxCurrentAspect = demuxer->getAspectRatio(); + int parx,pary; + int dxCurrentAspect = demuxer->getAspectRatio(&parx,&pary); if (dxCurrentAspect == Demuxer::ASPECT_4_3) { logger->log("Player", Log::DEBUG, "Demuxer said video is 4:3 aspect, switching TV"); - video->setAspectRatio(Video::ASPECT4X3); + video->setAspectRatio(Video::ASPECT4X3,parx,pary); Message* m = new Message(); m->from = this; @@ -990,7 +991,7 @@ void Player::call(void* caller) else if (dxCurrentAspect == Demuxer::ASPECT_16_9) { logger->log("Player", Log::DEBUG, "Demuxer said video is 16:9 aspect, switching TV"); - video->setAspectRatio(Video::ASPECT16X9); + video->setAspectRatio(Video::ASPECT16X9,parx,pary); Message* m = new Message(); m->from = this; @@ -1001,7 +1002,8 @@ void Player::call(void* caller) } else { - logger->log("Player", Log::DEBUG, "Demuxer said video is something else... ignoring"); + logger->log("Player", Log::DEBUG, "Demuxer said video is something else... setting it anyway"); + video->setAspectRatio(dxCurrentAspect,parx,pary); } } diff --git a/playerlivetv.cc b/playerlivetv.cc index f2fc417..20f25c4 100644 --- a/playerlivetv.cc +++ b/playerlivetv.cc @@ -223,13 +223,14 @@ void PlayerLiveTV::call(void* caller) { logger->log("PlayerLiveTV", Log::DEBUG, "Callback from demuxer"); - int dxCurrentAspect = demuxer->getAspectRatio(); + int parx,pary; + int dxCurrentAspect = demuxer->getAspectRatio(&parx,&pary); if (dxCurrentAspect == Demuxer::ASPECT_4_3) { if (video->getTVsize() == Video::ASPECT16X9) { logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer said video is 4:3 aspect, switching TV"); - video->setAspectRatio(Video::ASPECT4X3); + video->setAspectRatio(Video::ASPECT4X3,parx,pary); } else { @@ -248,7 +249,7 @@ void PlayerLiveTV::call(void* caller) if (video->getTVsize() == Video::ASPECT16X9) { logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer said video is 16:9 aspect, switching TV"); - video->setAspectRatio(Video::ASPECT16X9); + video->setAspectRatio(Video::ASPECT16X9,parx,pary); } else { @@ -264,7 +265,8 @@ void PlayerLiveTV::call(void* caller) } else { - logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer said video is something else... ignoring"); + logger->log("PlayerLiveTV", Log::DEBUG, "Demuxer said video is something else... switch anyway"); + video->setAspectRatio( dxCurrentAspect,parx,pary); } } else if (caller == &afeed) diff --git a/playermedia.cc b/playermedia.cc index 536ed4c..7cd314b 100644 --- a/playermedia.cc +++ b/playermedia.cc @@ -658,11 +658,12 @@ void PlayerMedia::call(void* caller) return; } - int dxCurrentAspect = demuxer->getAspectRatio(); + int parx,pary; + int dxCurrentAspect = demuxer->getAspectRatio(&parx,&pary); if (dxCurrentAspect == Demuxer::ASPECT_4_3) { logger->log("PlayerMedia", Log::DEBUG, "Demuxer said video is 4:3 aspect, switching TV"); - video->setAspectRatio(Video::ASPECT4X3); + video->setAspectRatio(Video::ASPECT4X3,parx,pary); Message* m = new Message(); m->from = this; @@ -674,7 +675,7 @@ void PlayerMedia::call(void* caller) else if (dxCurrentAspect == Demuxer::ASPECT_16_9) { logger->log("PlayerMedia", Log::DEBUG, "Demuxer said video is 16:9 aspect, switching TV"); - video->setAspectRatio(Video::ASPECT16X9); + video->setAspectRatio(Video::ASPECT16X9,parx,pary); Message* m = new Message(); m->from = this; @@ -685,7 +686,8 @@ void PlayerMedia::call(void* caller) } else { - logger->log("PlayerMedia", Log::DEBUG, "Demuxer said video is something else... ignoring"); + logger->log("PlayerMedia", Log::DEBUG, "Demuxer said video is something else... switch anayway"); + video->setAspectRatio(dxCurrentAspect,parx,pary); } } @@ -760,6 +762,7 @@ char * PlayerMedia::getInfo() { else { sprintf(brbuf,"CBR, %d kBit/s",br*4/10); } + int parx,pary; SNPRINTF(ibuf,500,"%s: %dx%d\n" "%s: %s\n" "%s: %s\n", @@ -767,7 +770,7 @@ char * PlayerMedia::getInfo() { demuxer->getHorizontalSize(), demuxer->getVerticalSize(), tr("Aspect"), - demuxer->getAspectRatio()==2?"4:3":"16:9", + demuxer->getAspectRatio(&parx,&pary)==2?"4:3":"16:9", tr("BitRate"),brbuf ); diff --git a/video.cc b/video.cc index 135d756..2c8bb56 100644 --- a/video.cc +++ b/video.cc @@ -36,6 +36,8 @@ Video::Video() aspectRatio = 0; mode = 0; tvsize = 0; + parx=1; + pary=1; screenWidth = 0; screenHeight = 0; diff --git a/video.h b/video.h index bacd8ea..2a670f5 100644 --- a/video.h +++ b/video.h @@ -50,7 +50,7 @@ class Video: public DrainTarget, public AbstractOption virtual UCHAR supportedTVFormats() { return 0;}; // if no selection is allowed virtual int setConnection(UCHAR connection)=0; - virtual int setAspectRatio(UCHAR aspectRatio)=0; // This one does the pin 8 scart widescreen switching + virtual int setAspectRatio(UCHAR aspectRatio, int tparx,int tpary)=0; // This one does the pin 8 scart widescreen switching virtual int setMode(UCHAR mode)=0; virtual int setTVsize(UCHAR size)=0; // Is the TV a widescreen? virtual void executePendingModeChanges() {}; // This is called if you change the output mode and the device take a while for reinitialization @@ -169,6 +169,7 @@ class Video: public DrainTarget, public AbstractOption UCHAR format; UCHAR connection; UCHAR aspectRatio; + int parx,pary; UCHAR mode; bool h264; diff --git a/videomvp.cc b/videomvp.cc index 7f12942..8820fe9 100644 --- a/videomvp.cc +++ b/videomvp.cc @@ -42,7 +42,7 @@ int VideoMVP::init(UCHAR tformat) if (!setFormat(tformat)) { shutdown(); return 0; } if (!setConnection(COMPOSITERGB)) { shutdown(); return 0; } - if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; } + if (!setAspectRatio(ASPECT4X3,12,11)) { shutdown(); return 0; } if (!setMode(NORMAL)) { shutdown(); return 0; } if (!setSource()) { shutdown(); return 0; } if (!attachFrameBuffer()) { shutdown(); return 0; } @@ -71,7 +71,7 @@ int VideoMVP::setTVsize(UCHAR ttvsize) tvsize = ttvsize; // Override the aspect ratio usage, temporarily use to set the video chip mode - if (!setAspectRatio(tvsize)) { shutdown(); return 0; } + if (!setAspectRatio(tvsize,parx,pary)) { shutdown(); return 0; } close(fdVideo); if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0; if (!setSource()) { shutdown(); return 0; } @@ -79,7 +79,7 @@ int VideoMVP::setTVsize(UCHAR ttvsize) // Reopening the fd causes the scart aspect line to go back to 4:3 // Set this again to the same as the tv screen size - if (!setAspectRatio(tvsize)) { shutdown(); return 0; } + if (!setAspectRatio(tvsize,parx,pary)) { shutdown(); return 0; } // mode == LETTERBOX is invalid if the TV is widescreen if (tvsize == ASPECT16X9) setMode(NORMAL); @@ -89,7 +89,7 @@ int VideoMVP::setTVsize(UCHAR ttvsize) int VideoMVP::setDefaultAspect() { - return setAspectRatio(tvsize); + return setAspectRatio(tvsize,parx,pary); } int VideoMVP::shutdown() @@ -148,9 +148,11 @@ int VideoMVP::setConnection(UCHAR tconnection) return 1; } -int VideoMVP::setAspectRatio(UCHAR taspectRatio) +int VideoMVP::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary) { if (!initted) return 0; + parx=tparx; + pary=tpary; if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; aspectRatio = taspectRatio; diff --git a/videomvp.h b/videomvp.h index 7a60daf..7b093c4 100644 --- a/videomvp.h +++ b/videomvp.h @@ -114,7 +114,7 @@ class VideoMVP : public Video int setFormat(UCHAR format); int setConnection(UCHAR connection); - int setAspectRatio(UCHAR aspectRatio); // This one does the pin 8 scart widescreen switching + int setAspectRatio(UCHAR aspectRatio, int tparx,int tpary); // This one does the pin 8 scart widescreen switching int setMode(UCHAR mode); int setTVsize(UCHAR size); // Is the TV a widescreen? int setDefaultAspect(); diff --git a/videoomx.cc b/videoomx.cc index 44f89da..c3456d9 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -77,7 +77,7 @@ int VideoOMX::init(UCHAR tformat) if (!setFormat(tformat)) { shutdown(); return 0; } if (!setConnection(HDMI)) { shutdown(); return 0; } - if (!setAspectRatio(ASPECT4X3)) { shutdown(); return 0; } + if (!setAspectRatio(ASPECT4X3,12,11)) { shutdown(); return 0; } if (!setMode(NORMAL)) { shutdown(); return 0; } if (!setSource()) { shutdown(); return 0; } if (!attachFrameBuffer()) { shutdown(); return 0; } @@ -321,7 +321,7 @@ void VideoOMX::executePendingModeChanges() int VideoOMX::setDefaultAspect() { - return setAspectRatio(tvsize); + return setAspectRatio(tvsize,parx,pary); } @@ -489,14 +489,17 @@ int VideoOMX::setConnection(UCHAR tconnection) return 1; } -int VideoOMX::setAspectRatio(UCHAR taspectRatio) +int VideoOMX::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary) { if (!initted) return 0; - if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; + //if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; aspectRatio = taspectRatio; + parx=tparx; + pary=tpary; - Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio); + Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i: PAR %d %d", aspectRatio,parx,pary); + updateMode(); // if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0; return 1; } @@ -514,6 +517,10 @@ void VideoOMX::updateMode() { clock_mutex.Lock(); if (omx_running) { + int oldcancelstate; + int oldcanceltype; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); OMX_ERRORTYPE error; OMX_CONFIG_DISPLAYREGIONTYPE dispconf; memset(&dispconf, 0, sizeof(dispconf)); @@ -530,6 +537,22 @@ void VideoOMX::updateMode() clock_mutex.Unlock(); return; } + + + dispconf.pixel_x =parx; + dispconf.pixel_y=pary; + dispconf.set = OMX_DISPLAY_SET_PIXEL; + error = OMX_SetParameter(omx_vid_rend, OMX_IndexConfigDisplayRegion, + &dispconf); + if (error != OMX_ErrorNone) { + Log::getInstance()->log("Video", Log::DEBUG, + "Set OMX_IndexConfigDisplayRegion5 failed %x", error); + clock_mutex.Unlock(); + return; + } + + + dispconf.set = OMX_DISPLAY_SET_FULLSCREEN; if (mode != QUARTER && mode != EIGHTH) { //Set Fullscreen @@ -594,6 +617,9 @@ void VideoOMX::updateMode() return; } } + clock_mutex.Unlock(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); } clock_mutex.Unlock(); diff --git a/videoomx.h b/videoomx.h index 3a7cb7a..286f084 100644 --- a/videoomx.h +++ b/videoomx.h @@ -78,7 +78,7 @@ class VideoOMX : public Video int setFormat(UCHAR format); int setConnection(UCHAR connection); - int setAspectRatio(UCHAR aspectRatio); // This one does the pin 8 scart widescreen switching + int setAspectRatio(UCHAR aspectRatio, int tparx,int tpary); // This one does the pin 8 scart widescreen switching int setMode(UCHAR mode); int setTVsize(UCHAR size); // Is the TV a widescreen? diff --git a/videowin.cc b/videowin.cc index 425ff00..06983da 100644 --- a/videowin.cc +++ b/videowin.cc @@ -146,7 +146,7 @@ int VideoWin::setTVsize(UCHAR ttvsize) int VideoWin::setDefaultAspect() { - return setAspectRatio(Video::ASPECT4X3); + return setAspectRatio(Video::ASPECT4X3,parx,pary); } int VideoWin::shutdown() @@ -184,9 +184,11 @@ int VideoWin::setConnection(UCHAR tconnection) return 1; } -int VideoWin::setAspectRatio(UCHAR taspectRatio) +int VideoWin::setAspectRatio(UCHAR taspectRatio, int tparx,int tpary) { if (!initted) return 0; + parx=tparx; + pary=tpary; if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; aspectRatio = taspectRatio; AdjustWindow(); diff --git a/videowin.h b/videowin.h index 3300433..7e43236 100644 --- a/videowin.h +++ b/videowin.h @@ -64,7 +64,7 @@ public: UCHAR supportedTVFormats() { return 0;}; int setConnection(UCHAR connection); - int setAspectRatio(UCHAR aspectRatio); // This one does the pin 8 scart widescreen switching + int setAspectRatio(UCHAR aspectRatio, int tparx,int tpary); // This one does the pin 8 scart widescreen switching UCHAR getAspectRatio(){return aspectRatio;}; UCHAR getMode(){return mode;}; UCHAR getPseudoTVsize() {return pseudotvsize;}; -- 2.39.2