コード例 #1
0
static void
mpegts_parse_reset_selected_programs (MpegTSParse2 * parse,
    gchar * program_numbers)
{
  GST_OBJECT_LOCK (parse);
  if (parse->program_numbers)
    g_free (parse->program_numbers);

  parse->program_numbers = program_numbers;

  if (*parse->program_numbers != '\0') {
    gint program_number;
    MpegTSParseProgram *program;
    gchar **progs, **walk;

    progs = g_strsplit (parse->program_numbers, ":", 0);

    walk = progs;
    while (*walk != NULL) {
      program_number = strtol (*walk, NULL, 0);
      program =
          (MpegTSParseProgram *) mpegts_base_get_program ((MpegTSBase *) parse,
          program_number);
      if (program == NULL)
        /* create the program, it will get activated once we get a PMT for it */
        program = (MpegTSParseProgram *) mpegts_base_add_program ((MpegTSBase *)
            parse, program_number, G_MAXUINT16);
      program->selected = 2;
      ++walk;
    }
    g_strfreev (progs);
  }

  g_hash_table_foreach (((MpegTSBase *) parse)->programs,
      foreach_program_activate_or_deactivate, parse);

  if (parse->pads_to_remove || parse->pads_to_add)
    parse->need_sync_program_pads = TRUE;
  GST_OBJECT_UNLOCK (parse);
}
コード例 #2
0
ファイル: mpegtsbase.c プロジェクト: jhgorse/gst-plugins-bad
static gboolean
mpegts_base_apply_pat (MpegTSBase * base, GstMpegtsSection * section)
{
  GPtrArray *pat = gst_mpegts_section_get_pat (section);
  GPtrArray *old_pat;
  MpegTSBaseProgram *program;
  gint i;

  if (G_UNLIKELY (pat == NULL))
    return FALSE;

  GST_INFO_OBJECT (base, "PAT");

  /* Applying a new PAT does two things:
   * * It adds the new programs to the list of programs this element handles
   *   and increments at the same time the number of times a program is referenced.
   *
   * * If there was a previously active PAT, It decrements the reference count
   *   of all program it used. If a program is no longer needed, it is removed.
   */

  old_pat = base->pat;
  base->pat = pat;

  GST_LOG ("Activating new Program Association Table");
  /* activate the new table */
  for (i = 0; i < pat->len; ++i) {
    GstMpegtsPatProgram *patp = g_ptr_array_index (pat, i);

    program = mpegts_base_get_program (base, patp->program_number);
    if (program) {
      /* IF the program already existed, just check if the PMT PID changed */
      if (program->pmt_pid != patp->network_or_program_map_PID) {
        if (program->pmt_pid != G_MAXUINT16) {
          /* pmt pid changed */
          /* FIXME: when this happens it may still be pmt pid of another
           * program, so setting to False may make it go through expensive
           * path in is_psi unnecessarily */
          MPEGTS_BIT_UNSET (base->known_psi, program->pmt_pid);
        }

        program->pmt_pid = patp->network_or_program_map_PID;
        if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->known_psi, program->pmt_pid)))
          GST_FIXME
              ("Refcounting issue. Setting twice a PMT PID (0x%04x) as know PSI",
              program->pmt_pid);
        MPEGTS_BIT_SET (base->known_psi, patp->network_or_program_map_PID);
      }
    } else {
      /* Create a new program */
      program =
          mpegts_base_add_program (base, patp->program_number,
          patp->network_or_program_map_PID);
    }
    /* We mark this program as being referenced by one PAT */
    program->patcount += 1;
  }

  if (old_pat) {
    MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base);
    /* deactivate the old table */
    GST_LOG ("Deactivating old Program Association Table");

    for (i = 0; i < old_pat->len; ++i) {
      GstMpegtsPatProgram *patp = g_ptr_array_index (old_pat, i);

      program = mpegts_base_get_program (base, patp->program_number);
      if (G_UNLIKELY (program == NULL)) {
        GST_DEBUG_OBJECT (base, "broken PAT, duplicated entry for program %d",
            patp->program_number);
        continue;
      }

      if (--program->patcount > 0)
        /* the program has been referenced by the new pat, keep it */
        continue;

      GST_INFO_OBJECT (base, "PAT removing program 0x%04x 0x%04x",
          patp->program_number, patp->network_or_program_map_PID);

      if (klass->can_remove_program (base, program)) {
        mpegts_base_deactivate_program (base, program);
        mpegts_base_remove_program (base, patp->program_number);
      }
      /* FIXME: when this happens it may still be pmt pid of another
       * program, so setting to False may make it go through expensive
       * path in is_psi unnecessarily */
      if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->known_psi,
                  patp->network_or_program_map_PID))) {
        GST_FIXME
            ("Program refcounting : Setting twice a pid (0x%04x) as known PSI",
            patp->network_or_program_map_PID);
      }
      MPEGTS_BIT_SET (base->known_psi, patp->network_or_program_map_PID);
      mpegts_packetizer_remove_stream (base->packetizer,
          patp->network_or_program_map_PID);
    }

    g_ptr_array_unref (old_pat);
  }

  return TRUE;
}