Ejemplo n.º 1
0
void free_demuxer(demuxer_t *demuxer)
{
    int i;
    mp_msg(MSGT_DEMUXER, MSGL_DBG2, "DEMUXER: freeing %s demuxer at %p\n",
           demuxer->desc->shortdesc, demuxer);
    if (demuxer->desc->close)
        demuxer->desc->close(demuxer);
    // Very ugly hack to make it behave like old implementation
    if (demuxer->desc->type == DEMUXER_TYPE_DEMUXERS)
        goto skip_streamfree;
    // free streams:
    for (i = 0; i < MAX_A_STREAMS; i++)
        if (demuxer->a_streams[i])
            free_sh_audio(demuxer, i);
    for (i = 0; i < MAX_V_STREAMS; i++)
        if (demuxer->v_streams[i])
            free_sh_video(demuxer->v_streams[i]);
    for (i = 0; i < MAX_S_STREAMS; i++)
        if (demuxer->s_streams[i])
            free_sh_sub(demuxer->s_streams[i]);
    // free demuxers:
    free_demuxer_stream(demuxer->audio);
    free_demuxer_stream(demuxer->video);
    free_demuxer_stream(demuxer->sub);
 skip_streamfree:
    free(demuxer->filename);
    if (demuxer->teletext)
        teletext_control(demuxer->teletext, TV_VBI_CONTROL_STOP, NULL);
    talloc_free(demuxer);
}
Ejemplo n.º 2
0
void update_teletext(sh_video_t *sh_video, demuxer_t *demuxer, int reset)
{
    int page_changed;

    if (!demuxer->teletext)
        return;

    //Also forcing page update when such ioctl is not supported or call error occured
    if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_IS_CHANGED,&page_changed)!=VBI_CONTROL_TRUE)
        page_changed=1;

    if(!page_changed)
        return;

    if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_VBIPAGE,&vo_osd_teletext_page)!=VBI_CONTROL_TRUE)
        vo_osd_teletext_page=NULL;
    if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_HALF_PAGE,&vo_osd_teletext_half)!=VBI_CONTROL_TRUE)
        vo_osd_teletext_half=0;
    if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_MODE,&vo_osd_teletext_mode)!=VBI_CONTROL_TRUE)
        vo_osd_teletext_mode=0;
    if(teletext_control(demuxer->teletext,TV_VBI_CONTROL_GET_FORMAT,&vo_osd_teletext_format)!=VBI_CONTROL_TRUE)
        vo_osd_teletext_format=0;
    vo_osd_changed(OSDTYPE_TELETEXT);

    teletext_control(demuxer->teletext,TV_VBI_CONTROL_MARK_UNCHANGED,NULL);
}
Ejemplo n.º 3
0
int tv_set_norm(tvi_handle_t *tvh, char* norm)
{
    tvh->norm = norm_from_string(tvh, norm);

    mp_msg(MSGT_TV, MSGL_V, "Selected norm : %s\n", norm);
    if (tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM, &tvh->norm) != TVI_CONTROL_TRUE) {
        mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_CannotSetNorm);
        return 0;
    }
    teletext_control(tvh->demuxer->teletext,TV_VBI_CONTROL_RESET,
                     &tvh->tv_param->teletext);
    return 1;
}
Ejemplo n.º 4
0
Archivo: tv.c Proyecto: HermiG/mplayer2
static int tv_set_norm_i(tvi_handle_t *tvh, int norm)
{
   tvh->norm = norm;

   mp_tmsg(MSGT_TV, MSGL_V, "Selected norm id: %d\n", norm);
   if (tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM, &tvh->norm) != TVI_CONTROL_TRUE) {
      mp_tmsg(MSGT_TV, MSGL_ERR, "Error: Cannot set norm!\n");
      return 0;
   }

   teletext_control(tvh->demuxer->teletext,TV_VBI_CONTROL_RESET,
                    &tvh->tv_param->teletext);
   return 1;
}
Ejemplo n.º 5
0
static int tv_set_norm_i(tvi_handle_t *tvh, int norm)
{
   tvh->norm = norm;

   mp_msg(MSGT_TV, MSGL_V, MSGTR_TV_SelectedNormId, norm);
   if (tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM, &tvh->norm) != TVI_CONTROL_TRUE) {
      mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_CannotSetNorm);
      return 0;
   }

   teletext_control(tvh->demuxer->teletext,TV_VBI_CONTROL_RESET,
                    &tvh->tv_param->teletext);
   return 1;
}
Ejemplo n.º 6
0
int tv_step_norm(tvi_handle_t *tvh)
{
    tvh->norm++;
    if (tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM,
                                &tvh->norm) != TVI_CONTROL_TRUE) {
        tvh->norm = 0;
        if (tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM,
                                    &tvh->norm) != TVI_CONTROL_TRUE) {
            mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_CannotSetNorm);
            return 0;
        }
    }
    teletext_control(tvh->demuxer->teletext,TV_VBI_CONTROL_RESET,
                     &tvh->tv_param->teletext);
    return 1;
}
Ejemplo n.º 7
0
int tv_set_freq(tvi_handle_t *tvh, unsigned long freq)
{
    if (tvh->functions->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) == TVI_CONTROL_TRUE)
    {
//	unsigned long freq = atof(tvh->tv_param->freq)*16;

        /* set freq in MHz */
        tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_SET_FREQ, &freq);

        tvh->functions->control(tvh->priv, TVI_CONTROL_TUN_GET_FREQ, &freq);
        mp_msg(MSGT_TV, MSGL_V, "Current frequency: %lu (%.3f)\n",
               freq, freq/16.0);
    }
    teletext_control(tvh->demuxer->teletext,TV_VBI_CONTROL_RESET,
                     &tvh->tv_param->teletext);
    return 1;
}
Ejemplo n.º 8
0
static demuxer_t* demux_open_tv(demuxer_t *demuxer)
{
    tvi_handle_t *tvh;
    sh_video_t *sh_video;
    sh_audio_t *sh_audio = NULL;
    const tvi_functions_t *funcs;

    demuxer->priv=NULL;
    if(!(tvh=tv_begin(demuxer->stream->priv))) return NULL;
    if (!tvh->functions->init(tvh->priv)) return NULL;

    tvh->demuxer = demuxer;
    tvh->functions->control(tvh->priv,TVI_CONTROL_VBI_INIT,
                            &(tvh->tv_param->teletext.device));
    tvh->functions->control(tvh->priv,TVI_CONTROL_GET_VBI_PTR,
                            &demuxer->teletext);

    if (!open_tv(tvh)) {
        tv_uninit(tvh);
        return NULL;
    }
    funcs = tvh->functions;
    demuxer->priv=tvh;

    sh_video = new_sh_video(demuxer, 0);

    /* get IMAGE FORMAT */
    funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format);
//    if (IMGFMT_IS_RGB(sh_video->format) || IMGFMT_IS_BGR(sh_video->format))
//	sh_video->format = 0x0;

    /* set FPS and FRAMETIME */

    if(!sh_video->fps)
    {
        float tmp;
        if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &tmp) != TVI_CONTROL_TRUE)
            sh_video->fps = 25.0f; /* on PAL */
        else sh_video->fps = tmp;
    }

    if (tvh->tv_param->fps != -1.0f)
        sh_video->fps = tvh->tv_param->fps;

    sh_video->frametime = 1.0f/sh_video->fps;

    /* If playback only mode, go to immediate mode, fail silently */
    if(tvh->tv_param->immediate == 1)
    {
        funcs->control(tvh->priv, TVI_CONTROL_IMMEDIATE, 0);
        tvh->tv_param->noaudio = 1;
    }

    /* disable TV audio if -nosound is present */
    if (!demuxer->audio || demuxer->audio->id == -2) {
        tvh->tv_param->noaudio = 1;
    }

    /* set width */
    funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w);

    /* set height */
    funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h);

    demuxer->video->sh = sh_video;
    sh_video->ds = demuxer->video;
    demuxer->video->id = 0;
    demuxer->seekable = 0;

    /* here comes audio init */
    if (tvh->tv_param->noaudio == 0 && funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
    {
        int audio_format;
        int sh_audio_format;
        char buf[128];

        /* yeah, audio is present */

        funcs->control(tvh->priv, TVI_CONTROL_AUD_SET_SAMPLERATE,
                       &tvh->tv_param->audiorate);

        if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE)
            goto no_audio;

        switch(audio_format)
        {
        case AF_FORMAT_U8:
        case AF_FORMAT_S8:
        case AF_FORMAT_U16_LE:
        case AF_FORMAT_U16_BE:
        case AF_FORMAT_S16_LE:
        case AF_FORMAT_S16_BE:
        case AF_FORMAT_S32_LE:
        case AF_FORMAT_S32_BE:
            sh_audio_format = 0x1; /* PCM */
            break;
        case AF_FORMAT_IMA_ADPCM:
        case AF_FORMAT_MU_LAW:
        case AF_FORMAT_A_LAW:
        case AF_FORMAT_MPEG2:
        default:
            mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnsupportedAudioType,
                   af_fmt2str(audio_format, buf, 128), audio_format);
            goto no_audio;
        }

        sh_audio = new_sh_audio(demuxer, 0, NULL);

        funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE,
                       &sh_audio->samplerate);
        funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE,
                       &sh_audio->samplesize);
        funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS,
                       &sh_audio->channels);

        sh_audio->format = sh_audio_format;
        sh_audio->sample_format = audio_format;

        sh_audio->i_bps = sh_audio->o_bps =
                              sh_audio->samplerate * sh_audio->samplesize *
                              sh_audio->channels;

        // emulate WF for win32 codecs:
        sh_audio->wf = malloc(sizeof(*sh_audio->wf));
        sh_audio->wf->wFormatTag = sh_audio->format;
        sh_audio->wf->nChannels = sh_audio->channels;
        sh_audio->wf->wBitsPerSample = sh_audio->samplesize * 8;
        sh_audio->wf->nSamplesPerSec = sh_audio->samplerate;
        sh_audio->wf->nBlockAlign = sh_audio->samplesize * sh_audio->channels;
        sh_audio->wf->nAvgBytesPerSec = sh_audio->i_bps;

        mp_msg(MSGT_DECVIDEO, MSGL_V, "  TV audio: %d channels, %d bits, %d Hz\n",
               sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample,
               sh_audio->wf->nSamplesPerSec);

        demuxer->audio->sh = sh_audio;
        sh_audio->ds = demuxer->audio;
        demuxer->audio->id = 0;
    }
no_audio:

    if(!(funcs->start(tvh->priv))) {
        // start failed :(
        tv_uninit(tvh);
        return NULL;
    }

    /* set color eq */
    tv_set_color_options(tvh, TV_COLOR_BRIGHTNESS, tvh->tv_param->brightness);
    tv_set_color_options(tvh, TV_COLOR_HUE, tvh->tv_param->hue);
    tv_set_color_options(tvh, TV_COLOR_SATURATION, tvh->tv_param->saturation);
    tv_set_color_options(tvh, TV_COLOR_CONTRAST, tvh->tv_param->contrast);

    if(tvh->tv_param->gain!=-1)
        if(funcs->control(tvh->priv,TVI_CONTROL_VID_SET_GAIN,&tvh->tv_param->gain)!=TVI_CONTROL_TRUE)
            mp_msg(MSGT_TV,MSGL_WARN,"Unable to set gain control!\n");

    teletext_control(demuxer->teletext,TV_VBI_CONTROL_RESET,
                     &tvh->tv_param->teletext);

    return demuxer;
}
Ejemplo n.º 9
0
void update_subtitles(sh_video_t *sh_video, double refpts, demux_stream_t *d_dvdsub, int reset)
{
    double curpts = refpts - sub_delay;
    unsigned char *packet=NULL;
    int len;
    int type = d_dvdsub->sh ? ((sh_sub_t *)d_dvdsub->sh)->type : 'v';
    static subtitle subs;
    if (reset) {
        sub_clear_text(&subs, MP_NOPTS_VALUE);
        if (vo_sub) {
            set_osd_subtitle(NULL);
        }
        if (vo_spudec) {
            spudec_reset(vo_spudec);
            vo_osd_changed(OSDTYPE_SPU);
        }
#ifdef CONFIG_FFMPEG
        if (is_av_sub(type))
            reset_avsub(d_dvdsub->sh);
#endif
    }
    // find sub
    if (subdata) {
        if (sub_fps==0) sub_fps = sh_video ? sh_video->fps : 25;
        current_module = "find_sub";
        if (refpts > sub_last_pts || refpts < sub_last_pts-1.0) {
            find_sub(subdata, curpts *
                     (subdata->sub_uses_time ? 100. : sub_fps));
            if (vo_sub) vo_sub_last = vo_sub;
            // FIXME! frame counter...
            sub_last_pts = refpts;
        }
    }

    // DVD sub:
    if (vo_config_count &&
        (vobsub_id >= 0 || type == 'v')) {
        int timestamp;
        current_module = "spudec";
        /* Get a sub packet from the DVD or a vobsub */
        while(1) {
            // Vobsub
            len = 0;
            if (vo_vobsub) {
                if (curpts >= 0) {
                    len = vobsub_get_packet(vo_vobsub, curpts,
                                            (void**)&packet, &timestamp);
                    if (len > 0) {
                        mp_dbg(MSGT_CPLAYER,MSGL_V,"\rVOB sub: len=%d v_pts=%5.3f v_timer=%5.3f sub=%5.3f ts=%d \n",len,refpts,sh_video->timer,timestamp / 90000.0,timestamp);
                    }
                }
            } else {
                // DVD sub
                len = ds_get_packet_sub(d_dvdsub, (unsigned char**)&packet, NULL, NULL);
                if (len > 0) {
                    // XXX This is wrong, sh_video->pts can be arbitrarily
                    // much behind demuxing position. Unfortunately using
                    // d_video->pts which would have been the simplest
                    // improvement doesn't work because mpeg specific hacks
                    // in video.c set d_video->pts to 0.
                    float x = d_dvdsub->pts - refpts;
                    if (x > -20 && x < 20) // prevent missing subs on pts reset
                        timestamp = 90000*d_dvdsub->pts;
                    else timestamp = 90000*curpts;
                    mp_dbg(MSGT_CPLAYER, MSGL_V, "\rDVD sub: len=%d  "
                           "v_pts=%5.3f  s_pts=%5.3f  ts=%d \n", len,
                           refpts, d_dvdsub->pts, timestamp);
                }
            }
            if (len<=0 || !packet) break;
            // create it only here, since with some broken demuxers we might
            // type = v but no DVD sub and we currently do not change the
            // "original frame size" ever after init, leading to wrong-sized
            // PGS subtitles.
            if (!vo_spudec)
                vo_spudec = spudec_new(NULL);
            if (vo_vobsub || timestamp >= 0)
                spudec_assemble(vo_spudec, packet, len, timestamp);
        }
    } else if (is_text_sub(type) || is_av_sub(type) || type == 'd') {
        int orig_type = type;
        double endpts;
        if (type == 'd' && !d_dvdsub->demuxer->teletext) {
            tt_stream_props tsp = {0};
            void *ptr = &tsp;
            if (teletext_control(NULL, TV_VBI_CONTROL_START, &ptr) == VBI_CONTROL_TRUE)
                d_dvdsub->demuxer->teletext = ptr;
        }
        if (d_dvdsub->non_interleaved)
            ds_get_next_pts(d_dvdsub);
        while (1) {
            double subpts = curpts;
            type = orig_type;
            len = ds_get_packet_sub(d_dvdsub, &packet, &subpts, &endpts);
            if (len < 0)
                break;
            if (is_av_sub(type)) {
#ifdef CONFIG_FFMPEG
                type = decode_avsub(d_dvdsub->sh, &packet, &len, &subpts, &endpts);
                if (type <= 0)
#endif
                    continue;
            }
            if (type == 'm') {
                if (len < 2) continue;
                len = FFMIN(len - 2, AV_RB16(packet));
                packet += 2;
            }
            if (type == 'd') {
                if (d_dvdsub->demuxer->teletext) {
                    uint8_t *p = packet;
                    p++;
                    len--;
                    while (len >= 46) {
                        int sublen = p[1];
                        if (p[0] == 2 || p[0] == 3)
                            teletext_control(d_dvdsub->demuxer->teletext,
                                TV_VBI_CONTROL_DECODE_DVB, p + 2);
                        p   += sublen + 2;
                        len -= sublen + 2;
                    }
                }
                continue;
            }
#ifdef CONFIG_ASS
            if (ass_enabled) {
                sh_sub_t* sh = d_dvdsub->sh;
                ass_track = sh ? sh->ass_track : NULL;
                if (!ass_track) continue;
                if (type == 'a') { // ssa/ass subs with libass
                    if (len > 10 && memcmp(packet, "Dialogue: ", 10) == 0)
                        ass_process_data(ass_track, packet, len);
                    else
                        ass_process_chunk(ass_track, packet, len,
                                          (long long)(subpts*1000 + 0.5),
                                          (long long)((endpts-subpts)*1000 + 0.5));
                } else { // plaintext subs with libass
                    if (subpts != MP_NOPTS_VALUE) {
                        subtitle tmp_subs = {0};
                        if (endpts == MP_NOPTS_VALUE) endpts = subpts + 3;
                        sub_add_text(&tmp_subs, packet, len, endpts, 0);
                        tmp_subs.start = subpts * 100;
                        tmp_subs.end = endpts * 100;
                        ass_process_subtitle(ass_track, &tmp_subs);
                        sub_clear_text(&tmp_subs, MP_NOPTS_VALUE);
                    }
                }
                continue;
            }
#endif
            if (subpts != MP_NOPTS_VALUE) {
                if (endpts == MP_NOPTS_VALUE)
                    sub_clear_text(&subs, MP_NOPTS_VALUE);
                if (type == 'a') { // ssa/ass subs without libass => convert to plaintext
                    int i;
                    unsigned char* p = packet;
                    int skip_commas = 8;
                    if (len > 10 && memcmp(packet, "Dialogue: ", 10) == 0)
                        skip_commas = 9;
                    for (i=0; i < skip_commas && *p != '\0'; p++)
                        if (*p == ',')
                            i++;
                    if (*p == '\0')  /* Broken line? */
                        continue;
                    len -= p - packet;
                    packet = p;
                }
                sub_add_text(&subs, packet, len, endpts, 1);
                set_osd_subtitle(&subs);
            }
            if (d_dvdsub->non_interleaved)
                ds_get_next_pts(d_dvdsub);
        }
        if (sub_clear_text(&subs, curpts))
            set_osd_subtitle(&subs);
    }
    if (vo_spudec) {
        spudec_heartbeat(vo_spudec, 90000*curpts);
        if (spudec_changed(vo_spudec))
            vo_osd_changed(OSDTYPE_SPU);
    }

    current_module=NULL;
}