int cAudio::setVolume(unsigned int left, unsigned int right) { // int avsfd; int ret; int vl = map_volume(left); int vr = map_volume(right); volume = (left + right) / 2; int v = map_volume(volume); if (clipfd != -1 && mixer_fd != -1) { int tmp = 0; /* not sure if left / right is correct here, but it is always the same anyways ;-) */ if (! Muted) tmp = left << 8 | right; ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp); if (ret == -1) lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, mixer_num, tmp); return ret; } // if (settings.volume_type == CControld::TYPE_OST || forcetype == (int)CControld::TYPE_OST) { AUDVOL vol; vol.frontleft = vl; vol.frontright = vr; vol.rearleft = vl; vol.rearright = vr; vol.center = v; vol.lfe = v; ret = ioctl(fd, MPEG_AUD_SET_VOL, &vol); if (ret < 0) lt_info("setVolume MPEG_AUD_SET_VOL failed (%m)\n"); return ret; } #if 0 else if (settings.volume_type == CControld::TYPE_AVS || forcetype == (int)CControld::TYPE_AVS)
void init_td_api() { if (!initialized) lt_debug_init(); lt_info("%s begin, initialized=%d, debug=0x%02x\n", __func__, (int)initialized, debuglevel); if (! glfb) { int x = 1280, y = 720; /* default OSD FB resolution */ /* * export GLFB_RESOLUTION=720,576 * to restore old default behviour */ const char *tmp = getenv("GLFB_RESOLUTION"); const char *p = NULL; if (tmp) p = strchr(tmp, ','); if (p) { x = atoi(tmp); y = atoi(p + 1); } lt_info("%s: setting GL Framebuffer size to %dx%d\n", __func__, x, y); if (!p) lt_info("%s: export GLFB_RESOLUTION=\"<w>,<h>\" to set another resolution\n", __func__); glfb = new GLFramebuffer(x, y); /* hard coded to PAL resolution for now */ } /* allow disabling of Audio/video decoders in case we just want to * valgrind-check other parts... export HAL_NOAVDEC=1 */ if (getenv("HAL_NOAVDEC")) HAL_nodec = true; /* hack, this triggers that the simple_display thread does not blit() once per second... */ setenv("SPARK_NOBLIT", "1", 1); initialized = true; }
int cAudio::PrepareClipPlay(int ch, int srate, int bits, int le) { lt_debug("%s ch %d srate %d bits %d le %d adevice %p\n", __func__, ch, srate, bits, le, adevice);; int driver; int byte_format = le ? AO_FMT_LITTLE : AO_FMT_BIG; if (sformat.bits != bits || sformat.channels != ch || sformat.rate != srate || sformat.byte_format != byte_format || adevice == NULL) { driver = ao_default_driver_id(); sformat.bits = bits; sformat.channels = ch; sformat.rate = srate; sformat.byte_format = byte_format; sformat.matrix = 0; if (adevice) ao_close(adevice); adevice = ao_open_live(driver, &sformat, NULL); ao_info *ai = ao_driver_info(driver); lt_info("%s: changed params ch %d srate %d bits %d le %d adevice %p\n", __func__, ch, srate, bits, le, adevice);; lt_info("libao driver: %d name '%s' short '%s' author '%s'\n", driver, ai->name, ai->short_name, ai->author); } return 0; };
bool cRecord::Stop(void) { lt_info("%s\n", __func__); if (pd->exit_flag != RECORD_RUNNING) lt_info("%s: status not RUNNING? (%d)\n", __func__, pd->exit_flag); pd->exit_flag = RECORD_STOPPED; if (pd->record_thread_running) pthread_join(pd->record_thread, NULL); pd->record_thread_running = false; if (pd->buf) free(pd->buf); pd->buf = NULL; /* We should probably do that from the destructor... */ if (!pd->dmx) lt_info("%s: dmx == NULL?\n", __func__); else delete pd->dmx; pd->dmx = NULL; if (pd->file_fd != -1) close(pd->file_fd); else lt_info("%s: file_fd not open??\n", __func__); pd->file_fd = -1; return true; }
/* the mutex makes sure that commands are not interspersed */ bool PBPrivate::rmfp_command(int cmd, int param, bool has_param, char *buf, int buflen) { lt_info("%s: %d %d %d %d\n", __func__, cmd, param, has_param, buflen); bool ret = true; int fd; if (cmd == 222) { if (pthread_mutex_trylock(&rmfp_cmd_mutex)) return false; } else pthread_mutex_lock(&rmfp_cmd_mutex); unlink(OUT_FILE); if (has_param) { fd = open(IN_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666); dprintf(fd, "%i", param); close(fd); } fd = open(CMD_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666); dprintf(fd, "%i", cmd); close(fd); int n = 0, m = 0; if (buflen > 0) { while ((fd = open(OUT_FILE, O_RDONLY)) == -1) { if (++m > 500) { /* don't wait more than 5 seconds */ lt_info("%s: timed out waiting for %s (cmd %d par %d buflen %d\n", __func__, OUT_FILE, cmd, param, buflen); ret = false; goto out; } usleep(10000); } unlink(OUT_FILE); n = read(fd, buf, buflen); close(fd); /* some commands (CUSTOM_COMMAND_GET_AUDIO_BY_ID for example) actually * return the answer in two successive writes, as we are not using the * FIFO, we need to make sure that the file is deleted immediately, because * rmfp_player will not overwrite it if it exists */ while ((fd = open(OUT_FILE, O_RDONLY)) == -1) { if (++m > 10) break; usleep(1000); } if (fd > -1) { read(fd, buf + n, buflen - n); unlink(OUT_FILE); close(fd); } buf[buflen - 1] = '0'; } out: pthread_mutex_unlock(&rmfp_cmd_mutex); if (cmd != 222) /* called tooo often :-) */ lt_info("%s: reply: '%s' ret: %d m:%d\n", __func__, buf?buf:"(none)", ret, m); return ret; }
void cVideo::routeVideo(int standby) { lt_debug("%s(%d)\n", __FUNCTION__, standby); int avsfd = open("/dev/stb/tdsystem", O_RDONLY); if (avsfd < 0) { perror("open tdsystem"); return; } /* in standby, we always route VCR scart to the TV. Once there is a UI to configure this, we can think more about this... */ if (standby) { lt_info("%s set fastblank and pin8 to follow VCR SCART, route VCR to TV\n", __FUNCTION__); if (ioctl(avsfd, IOC_AVS_FASTBLANK_SET, (unsigned char)3) < 0) perror("IOC_AVS_FASTBLANK_SET, 3"); /* TODO: should probably depend on aspect ratio setting */ if (ioctl(avsfd, IOC_AVS_SCART_PIN8_FOLLOW_VCR) < 0) perror("IOC_AVS_SCART_PIN8_FOLLOW_VCR"); if (ioctl(avsfd, IOC_AVS_ROUTE_VCR2TV) < 0) perror("IOC_AVS_ROUTE_VCR2TV"); } else { unsigned char fblk = 1; lt_info("%s set fastblank=%d pin8=%dV, route encoder to TV\n", __FUNCTION__, fblk, scartvoltage); if (ioctl(avsfd, IOC_AVS_FASTBLANK_SET, fblk) < 0) perror("IOC_AVS_FASTBLANK_SET, fblk"); if (!noscart && ioctl(avsfd, IOC_AVS_SCART_PIN8_SET, scartvoltage) < 0) perror("IOC_AVS_SCART_PIN8_SET"); if (ioctl(avsfd, IOC_AVS_ROUTE_ENC2TV) < 0) perror("IOC_AVS_ROUTE_ENC2TV"); } close(avsfd); }
void init_td_api() { if (!initialized) lt_debug_init(); lt_info("%s begin, initialized=%d, debug=0x%02x\n", __FUNCTION__, (int)initialized, debuglevel); if (!initialized) { /* this is a strange hack: the drivers seem to only work correctly after * demux0 has been used once. After that, we can use demux1,2,... */ struct dmx_pes_filter_params p; int dmx = open("/dev/dvb/adapter0/demux0", O_RDWR|O_CLOEXEC); if (dmx < 0) lt_info("%s: ERROR open /dev/dvb/adapter0/demux0 (%m)\n", __func__); else { memset(&p, 0, sizeof(p)); p.output = DMX_OUT_DECODER; p.input = DMX_IN_FRONTEND; p.flags = DMX_IMMEDIATE_START; p.pes_type = DMX_PES_VIDEO; ioctl(dmx, DMX_SET_PES_FILTER, &p); ioctl(dmx, DMX_STOP); close(dmx); } } initialized = true; lt_info("%s end\n", __FUNCTION__); }
cPlayback::cPlayback(int num) { lt_info( "%s:%s\n", FILENAME, __FUNCTION__); const gchar *nano_str; guint major, minor, micro, nano; gst_init(NULL, NULL); gst_version (&major, &minor, µ, &nano); if (nano == 1) nano_str = "(CVS)"; else if (nano == 2) nano_str = "(Prerelease)"; else nano_str = ""; lt_info( "%s:%s - This program is linked against GStreamer %d.%d.%d %s\n", FILENAME, __FUNCTION__, major, minor, micro, nano_str); mAudioStream = 0; mSpeed = 0; playing = false; playstate = STATE_STOP; }
bool cRecord::Start(int fd, unsigned short vpid, unsigned short * apids, int numpids) { lt_info("%s: fd %d, vpid 0x%03x\n", __func__, fd, vpid); int i; if (!dmx) dmx = new cDemux(1); dmx->Open(DMX_TP_CHANNEL, NULL, 0); dmx->pesFilter(vpid); for (i = 0; i < numpids; i++) dmx->addPid(apids[i]); file_fd = fd; exit_flag = RECORD_RUNNING; if (posix_fadvise(file_fd, 0, 0, POSIX_FADV_DONTNEED)) perror("posix_fadvise"); i = pthread_create(&record_thread, 0, execute_record_thread, this); if (i != 0) { exit_flag = RECORD_FAILED_READ; errno = i; lt_info("%s: error creating thread! (%m)\n", __func__); delete dmx; dmx = NULL; return false; } record_thread_running = true; return true; }
cRecord::~cRecord() { lt_info("%s: calling ::Stop()\n", __func__); Stop(); delete pd; pd = NULL; lt_info("%s: end\n", __func__); }
void cAudio::openDevice(void) { if (fd < 0) { if ((fd = open(AUDIO_DEVICE, O_RDWR)) < 0) lt_info("openDevice: open failed (%m)\n"); fcntl(fd, F_SETFD, FD_CLOEXEC); do_mute(true, false); } else lt_info("openDevice: already open (fd = %d)\n", fd); }
bool cRecord::AddPid(unsigned short pid) { std::vector<pes_pids> pids; lt_info("%s: \n", __func__); if (!dmx) { lt_info("%s: DMX = NULL\n", __func__); return false; } pids = dmx->getPesPids(); for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) { if ((*i).pid == pid) return true; /* or is it an error to try to add the same PID twice? */ } return dmx->addPid(pid); }
cVideo::cVideo(int, void *, void *) { lt_debug("%s\n", __FUNCTION__); if ((fd = open(VIDEO_DEVICE, O_RDWR)) < 0) lt_info("%s cannot open %s: %m\n", __FUNCTION__, VIDEO_DEVICE); fcntl(fd, F_SETFD, FD_CLOEXEC); playstate = VIDEO_STOPPED; croppingMode = VID_DISPMODE_NORM; outputformat = VID_OUTFMT_RGBC_SVIDEO; scartvoltage = -1; z[0] = 100; z[1] = 100; zoomvalue = &z[0]; const char *blanknames[2] = { "/share/tuxbox/blank_576.mpg", "/share/tuxbox/blank_480.mpg" }; int blankfd; struct stat st; for (int i = 0; i < 2; i++) { blank_data[i] = NULL; /* initialize */ blank_size[i] = 0; blankfd = open(blanknames[i], O_RDONLY); if (blankfd < 0) { lt_info("%s cannot open %s: %m", __FUNCTION__, blanknames[i]); continue; } if (fstat(blankfd, &st) != -1 && st.st_size > 0) { blank_size[i] = st.st_size; blank_data[i] = malloc(blank_size[i]); if (! blank_data[i]) lt_info("%s malloc failed (%m)\n", __FUNCTION__); else if (read(blankfd, blank_data[i], blank_size[i]) != blank_size[i]) { lt_info("%s short read (%m)\n", __FUNCTION__); free(blank_data[i]); /* don't leak... */ blank_data[i] = NULL; } } close(blankfd); } video_standby = 0; noscart = (getenv("TRIPLE_NOSCART") != NULL); if (noscart) lt_info("%s TRIPLE_NOSCART variable prevents SCART switching\n", __FUNCTION__); }
void init_td_api() { if (!initialized) lt_debug_init(); lt_info("%s begin, initialized=%d, debug=0x%02x\n", __func__, (int)initialized, debuglevel); initialized = true; }
int cVideo::SetVideoSystem(int video_system, bool remember) { lt_info("%s(%d, %d)\n", __FUNCTION__, video_system, remember); if (video_system > VID_DISPFMT_SECAM || video_system < 0) video_system = VID_DISPFMT_PAL; return fop(ioctl, MPEG_VID_SET_DISPFMT, video_system); }
void shutdown_td_api() { lt_info("%s, initialized = %d\n", __func__, (int)initialized); if (glfb) delete glfb; initialized = false; }
int cAudio::do_mute(bool enable, bool remember) { lt_debug("%s(%d, %d)\n", __FUNCTION__, enable, remember); int avsfd; int ret; if (remember) Muted = enable; ret = ioctl(fd, MPEG_AUD_SET_MUTE, enable); if (ret < 0) lt_info("%s(%d) failed (%m)\n", __FUNCTION__, (int)enable); /* are we using alternative DSP / mixer? */ if (clipfd != -1 || mixer_fd != -1) setVolume(volume,volume); /* considers "Muted" variable, "remember" is basically always true in this context */ avsfd = open("/dev/stb/tdsystem", O_RDONLY); if (avsfd >= 0) { if (enable) ioctl(avsfd, IOC_AVS_SET_VOLUME, 31); else ioctl(avsfd, IOC_AVS_SET_VOLUME, 0); close(avsfd); } return ret; }
cRecord::cRecord(int /*num*/) { lt_info("%s\n", __func__); dmx = NULL; record_thread_running = false; file_fd = -1; exit_flag = RECORD_STOPPED; }
// used by movieplay void cPlayback::Close(void) { lt_info( "%s:%s\n", FILENAME, __FUNCTION__); Stop(); // disconnect bus handler if (m_gst_playbin) { // disconnect sync handler callback GstBus * bus = gst_pipeline_get_bus(GST_PIPELINE (m_gst_playbin)); gst_bus_set_sync_handler(bus, NULL, NULL); gst_object_unref(bus); lt_info( "%s:%s - GST bus handler closed\n", FILENAME, __FUNCTION__); } if (m_stream_tags) gst_tag_list_free(m_stream_tags); // close gst if (m_gst_playbin) { if (audioSink) { gst_object_unref(GST_OBJECT(audioSink)); audioSink = NULL; lt_info( "%s:%s - GST audio Sink closed\n", FILENAME, __FUNCTION__); } if (videoSink) { gst_object_unref(GST_OBJECT(videoSink)); videoSink = NULL; lt_info( "%s:%s - GST video Sink closed\n", FILENAME, __FUNCTION__); } // unref m_gst_playbin gst_object_unref (GST_OBJECT (m_gst_playbin)); lt_info( "%s:%s - GST playbin closed\n", FILENAME, __FUNCTION__); m_gst_playbin = NULL; } }
bool cCpuFreqManager::SetCpuFreq(unsigned long f) { /* actually SetCpuFreq is used to determine if the system is in standby this is an "elegant" hack, because: * during a recording, cpu freq is kept "high", even if the box is sent to standby * the "SetStandby" call is made even if a recording is running On the TD, setting standby disables the frontend, so we must not do it if a recording is running. For now, the values in neutrino are hardcoded: * f == 0 => max => not standby * f == 50000000 => min => standby */ lt_debug("%s(%lu) => set standby = %s\n", __FUNCTION__, f, f?"true":"false"); int fd = open("/dev/stb/tdsystem", O_RDONLY); if (fd < 0) { perror("open tdsystem"); return false; } if (f) { ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ ioctl(fd, IOC_AVS_STANDBY_ENTER); if (getenv("TRIPLE_LCDBACKLIGHT")) { lt_info("%s: TRIPLE_LCDBACKLIGHT is set: keeping LCD backlight on\n", __func__); close(fd); fd = open("/dev/stb/tdlcd", O_RDONLY); if (fd < 0) lt_info("%s: open tdlcd error: %m\n", __func__); else ioctl(fd, IOC_LCD_BACKLIGHT_ON); } } else { ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ ioctl(fd, IOC_AVS_STANDBY_LEAVE); /* unmute will be done by cAudio::do_mute(). Ugly, but prevents pops */ // ioctl(fd, IOC_AVS_SET_VOLUME, 0); /* max gain */ } close(fd); return true; }
bool cPlayback::Play(void) { lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); if(playing == true) return true; if(m_gst_playbin) { gst_element_set_state(GST_ELEMENT(m_gst_playbin), GST_STATE_PLAYING); playing = true; playstate = STATE_PLAY; } lt_info("%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); return playing; }
bool cPlayback::SyncAV(void) { lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); if(playing == false ) return false; return true; }
int cAudio::WriteClip(unsigned char *buffer, int size) { lt_debug("cAudio::%s buf 0x%p size %d\n", __func__, buffer, size); if (!adevice) { lt_info("%s: adevice not opened?\n", __func__); return 0; } ao_play(adevice, (char *)buffer, size); return size; };
bool cPlayback::Stop(void) { if(playing == false) return false; lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); // stop if(m_gst_playbin) { gst_element_set_state(m_gst_playbin, GST_STATE_NULL); } playing = false; lt_info( "%s:%s playing %d\n", FILENAME, __FUNCTION__, playing); playstate = STATE_STOP; return true; }
int cVideo::setAspectRatio(int vformat, int cropping) { lt_info("%s(%d, %d)\n", __func__, vformat, cropping); if (vformat >= 0) display_aspect = (DISPLAY_AR) vformat; if (cropping >= 0) display_crop = (DISPLAY_AR_MODE) cropping; if (display_aspect < DISPLAY_AR_RAW) /* don't know what to do with this */ glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop); return 0; }
bool cRecord::Start(int fd, unsigned short vpid, unsigned short *apids, int numpids, uint64_t) { lt_info("%s: fd %d, vpid 0x%03x\n", __func__, fd, vpid); int i; if (!pd->dmx) pd->dmx = new cDemux(pd->dmx_num); pd->dmx->Open(DMX_TP_CHANNEL, NULL, 2*1024*1024); pd->dmx->pesFilter(vpid); for (i = 0; i < numpids; i++) pd->dmx->addPid(apids[i]); pd->file_fd = fd; pd->exit_flag = RECORD_RUNNING; if (posix_fadvise(pd->file_fd, 0, 0, POSIX_FADV_DONTNEED)) perror("posix_fadvise"); pd->buf = (uint8_t *)malloc(bufsize); if (!pd->buf) { i = errno; lt_info("%s: unable to allocate read buffer of %d bytes (%m)\n", __func__, bufsize); } else i = pthread_create(&pd->record_thread, 0, execute_record_thread, pd); if (i != 0) { pd->exit_flag = RECORD_FAILED_READ; errno = i; lt_info("%s: error creating thread! (%m)\n", __func__); delete pd->dmx; pd->dmx = NULL; free(pd->buf); pd->buf = NULL; return false; } pd->record_thread_running = true; return true; }
bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int numapids) { std::vector<pes_pids> pids; cDemux *dmx = pd->dmx; int j; bool found; unsigned short pid; lt_info("%s\n", __func__); if (!dmx) { lt_info("%s: DMX = NULL\n", __func__); return false; } pids = dmx->pesfds; /* the first PID is the video pid, so start with the second PID... */ for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { found = false; pid = (*i).pid; for (j = 0; j < numapids; j++) { if (pid == apids[j]) { found = true; break; } } if (!found) dmx->removePid(pid); } for (j = 0; j < numapids; j++) { found = false; for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { if ((*i).pid == apids[j]) { found = true; break; } } if (!found) dmx->addPid(apids[j]); } return true; }
int cVideo::SetVideoSystem(int system, bool) { int h; switch(system) { case VIDEO_STD_NTSC: case VIDEO_STD_480P: h = 480; break; case VIDEO_STD_1080I60: case VIDEO_STD_1080I50: case VIDEO_STD_1080P30: case VIDEO_STD_1080P24: case VIDEO_STD_1080P25: case VIDEO_STD_1080P50: h = 1080; break; case VIDEO_STD_720P50: case VIDEO_STD_720P60: h = 720; break; case VIDEO_STD_AUTO: lt_info("%s: VIDEO_STD_AUTO not implemented\n", __func__); // fallthrough case VIDEO_STD_SECAM: case VIDEO_STD_PAL: case VIDEO_STD_576P: h = 576; break; default: lt_info("%s: unhandled value %d\n", __func__, system); return 0; } v_std = (VIDEO_STD) system; output_h = h; if (display_aspect < DISPLAY_AR_RAW) /* don't know what to do with this */ glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop); return 0; }
int cAudio::StopClip() { lt_debug("%s\n", __func__); #if 0 /* don't do anything - closing / reopening ao all the time makes for long delays * reinit on-demand (e.g. for changed parameters) instead */ if (!adevice) { lt_info("%s: adevice not opened?\n", __func__); return 0; } ao_close(adevice); adevice = NULL; #endif return 0; };
bool cPlayback::SetAPid(int pid , bool /*ac3*/) { lt_info("%s: pid %i\n", __func__, pid); int current_audio; if(pid != mAudioStream) { g_object_set (G_OBJECT (m_gst_playbin), "current-audio", pid, NULL); printf("%s: switched to audio stream %i\n", __FUNCTION__, pid); mAudioStream = pid; } return true; }