static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message) { DvbBaseBin *dvbbasebin; dvbbasebin = GST_DVB_BASE_BIN (bin); /* note: message->src might be a GstPad, so use element cast w/o typecheck */ if (GST_ELEMENT_CAST (message->src) == dvbbasebin->tsparse) { GstMpegtsSection *section = gst_message_parse_mpegts_section (message); if (section) { switch (GST_MPEGTS_SECTION_TYPE (section)) { case GST_MPEGTS_SECTION_PAT: dvb_base_bin_pat_info_cb (dvbbasebin, section); break; case GST_MPEGTS_SECTION_PMT: dvb_base_bin_pmt_info_cb (dvbbasebin, section); break; default: break; } gst_mpegts_section_unref (section); } } /* chain up */ GST_BIN_CLASS (parent_class)->handle_message (bin, message); }
static void mpegts_base_handle_psi (MpegTSBase * base, GstMpegTsSection * section) { gboolean post_message = TRUE; GST_DEBUG ("Handling PSI (pid: 0x%04x , table_id: 0x%02x)", section->pid, section->table_id); switch (section->section_type) { case GST_MPEGTS_SECTION_PAT: post_message = mpegts_base_apply_pat (base, section); if (base->seen_pat == FALSE) { base->seen_pat = TRUE; GST_DEBUG ("First PAT offset: %" G_GUINT64_FORMAT, section->offset); mpegts_packetizer_set_reference_offset (base->packetizer, section->offset); } break; case GST_MPEGTS_SECTION_PMT: post_message = mpegts_base_apply_pmt (base, section); break; case GST_MPEGTS_SECTION_EIT: /* some tag xtraction + posting */ post_message = mpegts_base_get_tags_from_eit (base, section); break; default: break; } /* Finally post message (if it wasn't corrupted) */ if (post_message) gst_element_post_message (GST_ELEMENT_CAST (base), gst_message_new_mpegts_section (GST_OBJECT (base), section)); gst_mpegts_section_unref (section); }
static void dvb_base_bin_program_destroy (gpointer data) { DvbBaseBinProgram *program; program = (DvbBaseBinProgram *) data; if (program->pmt) { program->pmt = NULL; gst_mpegts_section_unref (program->section); } g_free (program); }
static void mpegts_base_free_program (MpegTSBaseProgram * program) { GList *tmp; if (program->pmt) { gst_mpegts_section_unref (program->section); program->pmt = NULL; } for (tmp = program->stream_list; tmp; tmp = tmp->next) g_free (tmp->data); if (program->stream_list) g_list_free (program->stream_list); g_free (program->streams); if (program->tags) gst_tag_list_unref (program->tags); g_free (program); }
static void _on_bus_message (GstBus * bus, GstMessage * message, GMainLoop * mainloop) { /* g_printf ("Got message %s\n", GST_MESSAGE_TYPE_NAME (message)); */ switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: case GST_MESSAGE_EOS: g_main_loop_quit (mainloop); break; case GST_MESSAGE_ELEMENT: { GstMpegTsSection *section; if ((section = gst_message_parse_mpegts_section (message))) { g_print ("Got section: PID:0x%04x type:%s (table_id 0x%02x (%s)) at offset %" G_GUINT64_FORMAT "\n", section->pid, enum_name (GST_TYPE_MPEG_TS_SECTION_TYPE, section->section_type), section->table_id, enum_name (GST_TYPE_MPEG_TS_SECTION_TABLE_ID, section->table_id), section->offset); if (!section->short_section) { g_print (" subtable_extension:0x%04x, version_number:0x%02x\n", section->subtable_extension, section->version_number); g_print (" section_number:0x%02x last_section_number:0x%02x crc:0x%08x\n", section->section_number, section->last_section_number, section->crc); } dump_section (section); g_printf ("\n\n"); gst_mpegts_section_unref (section); } break; } default: break; } }
static void dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, GstMpegtsSection * section) { const GstMpegtsPMT *pmt; DvbBaseBinProgram *program; guint program_number; pmt = gst_mpegts_section_get_pmt (section); if (G_UNLIKELY (pmt == NULL)) { GST_WARNING_OBJECT (dvbbasebin, "Received invalid PMT"); return; } program_number = section->subtable_extension; program = dvb_base_bin_get_program (dvbbasebin, program_number); if (program == NULL) { GST_WARNING ("got PMT for program %d but program not in PAT", program_number); program = dvb_base_bin_add_program (dvbbasebin, program_number); } program->old_pmt = program->pmt; program->old_section = program->section; program->pmt = pmt; program->section = gst_mpegts_section_ref (section); /* activate the program if it's selected and either it's not active or its pmt * changed */ if (program->selected && (!program->active || program->old_pmt != NULL)) dvb_base_bin_activate_program (dvbbasebin, program); if (program->old_pmt) { gst_mpegts_section_unref (program->old_section); program->old_pmt = NULL; } }
static void mpegts_base_activate_program (MpegTSBase * base, MpegTSBaseProgram * program, guint16 pmt_pid, GstMpegtsSection * section, const GstMpegtsPMT * pmt, gboolean initial_program) { guint i; MpegTSBaseClass *klass; if (G_UNLIKELY (program->active)) return; GST_DEBUG ("Activating program %d", program->program_number); /* activate new pmt */ if (program->section) gst_mpegts_section_unref (program->section); program->section = gst_mpegts_section_ref (section); program->pmt = pmt; program->pmt_pid = pmt_pid; program->pcr_pid = pmt->pcr_pid; /* extract top-level registration_id if present */ program->registration_id = get_registration_from_descriptors (pmt->descriptors); GST_DEBUG ("program 0x%04x, registration_id %" SAFE_FOURCC_FORMAT, program->program_number, SAFE_FOURCC_ARGS (program->registration_id)); for (i = 0; i < pmt->streams->len; ++i) { GstMpegtsPMTStream *stream = g_ptr_array_index (pmt->streams, i); switch (stream->stream_type) { case GST_MPEGTS_STREAM_TYPE_SCTE_DSMCC_DCB: case GST_MPEGTS_STREAM_TYPE_SCTE_SIGNALING: { guint32 registration_id = get_registration_from_descriptors (stream->descriptors); /* Not a private section stream */ if (registration_id != DRF_ID_CUEI && registration_id != DRF_ID_ETV1) break; /* Fall through on purpose - remove this PID from known_psi */ } case GST_MPEGTS_STREAM_TYPE_PRIVATE_SECTIONS: case GST_MPEGTS_STREAM_TYPE_MHEG: case GST_MPEGTS_STREAM_TYPE_DSM_CC: case GST_MPEGTS_STREAM_TYPE_DSMCC_A: case GST_MPEGTS_STREAM_TYPE_DSMCC_B: case GST_MPEGTS_STREAM_TYPE_DSMCC_C: case GST_MPEGTS_STREAM_TYPE_DSMCC_D: case GST_MPEGTS_STREAM_TYPE_SL_FLEXMUX_SECTIONS: case GST_MPEGTS_STREAM_TYPE_METADATA_SECTIONS: /* Set known PSI streams */ if (base->parse_private_sections) MPEGTS_BIT_SET (base->known_psi, stream->pid); break; default: if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->is_pes, stream->pid))) GST_FIXME ("Refcounting issue. Setting twice a PID (0x%04x) as known PES", stream->pid); if (G_UNLIKELY (MPEGTS_BIT_IS_SET (base->known_psi, stream->pid))) { GST_FIXME ("Refcounting issue. Setting a known PSI PID (0x%04x) as known PES", stream->pid); MPEGTS_BIT_UNSET (base->known_psi, stream->pid); } MPEGTS_BIT_SET (base->is_pes, stream->pid); break; } mpegts_base_program_add_stream (base, program, stream->pid, stream->stream_type, stream); } /* We add the PCR pid last. If that PID is already used by one of the media * streams above, no new stream will be created */ mpegts_base_program_add_stream (base, program, pmt->pcr_pid, -1, NULL); MPEGTS_BIT_SET (base->is_pes, pmt->pcr_pid); program->active = TRUE; program->initial_program = initial_program; klass = GST_MPEGTS_BASE_GET_CLASS (base); if (klass->program_started != NULL) klass->program_started (base, program); GST_DEBUG_OBJECT (base, "new pmt activated"); }