static gboolean gst_x265_enc_set_level_tier_and_profile (GstX265Enc * encoder, GstCaps * caps) { x265_nal *nal, *vps_nal; guint32 i_nal; int header_return; GST_DEBUG_OBJECT (encoder, "set profile, level and tier"); header_return = x265_encoder_headers (encoder->x265enc, &nal, &i_nal); if (header_return < 0) { GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x265 header failed."), ("x265_encoder_headers return code=%d", header_return)); return FALSE; } GST_DEBUG_OBJECT (encoder, "%d nal units in header", i_nal); g_assert (nal[0].type == NAL_UNIT_VPS); vps_nal = gst_x265_enc_bytestream_to_nal (&nal[0]); GST_MEMDUMP ("VPS", vps_nal->payload, vps_nal->sizeBytes); if (!gst_codec_utils_h265_caps_set_level_tier_and_profile (caps, vps_nal->payload + 6, vps_nal->sizeBytes - 6)) { GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x265 failed."), ("Failed to find correct level, tier or profile in VPS")); return FALSE; } x265_nal_free (vps_nal); return TRUE; }
/** * gst_codec_utils_h265_get_profile: * @profile_tier_level: Pointer to the profile_tier_level * structure for the stream. * @len: Length of the data available in @profile_tier_level * * Converts the profile indication (general_profile_idc) in the stream's * profile_level_tier structure into a string. The profile_tier_level is * expected to have the following format, as defined in the H.265 * specification. The profile_tier_level is viewed as a bitstream here, * with bit 0 being the most significant bit of the first byte. * * <itemizedlist> * <listitem><para>Bit 0:1 - general_profile_space</para></listitem> * <listitem><para>Bit 2 - general_tier_flag</para></listitem> * <listitem><para>Bit 3:7 - general_profile_idc</para></listitem> * <listitem><para>Bit 8:39 - gernal_profile_compatibility_flags</para></listitem> * <listitem><para>Bit 40 - general_progressive_source_flag</para></listitem> * <listitem><para>Bit 41 - general_interlaced_source_flag</para></listitem> * <listitem><para>Bit 42 - general_non_packed_constraint_flag</para></listitem> * <listitem><para>Bit 43 - general_frame_only_constraint_flag</para></listitem> * <listitem><para>Bit 44:87 - general_reserved_zero_44bits</para></listitem> * <listitem><para>Bit 88:95 - general_level_idc</para></listitem> * </itemizedlist> * * Returns: The profile as a const string, or %NULL if there is an error. * * Since 1.4 */ const gchar * gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level, guint len) { const gchar *profile = NULL; gint gpcf1 = 0, gpcf2 = 0, gpcf3 = 0; gint profile_idc; g_return_val_if_fail (profile_tier_level != NULL, NULL); if (len < 2) return NULL; GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len); profile_idc = (profile_tier_level[0] & 0x1f); gpcf1 = (profile_tier_level[1] & 0x40) >> 6; gpcf2 = (profile_tier_level[1] & 0x20) >> 5; gpcf3 = (profile_tier_level[1] & 0x10) >> 4; if (profile_idc == 1 || gpcf1) profile = "main"; else if (profile_idc == 2 || gpcf2) profile = "main-10"; else if (profile_idc == 3 || gpcf3) profile = "main-still-picture"; else profile = NULL; return profile; }
static void rtp_jpeg_do_packet_loss (gdouble prob, gint num_expected) { GstHarness *h; gboolean eos = FALSE; gchar *s; guint i, buffer_count; s = g_strdup_printf ("videotestsrc pattern=ball num-buffers=100 ! " "jpegenc quality=50 ! rtpjpegpay ! identity drop-probability=%g ! " "rtpjpegdepay", prob); GST_INFO ("running pipeline %s", s); h = gst_harness_new_parse (s); g_free (s); gst_harness_play (h); do { GstEvent *event; event = gst_harness_pull_event (h); eos = (GST_EVENT_TYPE (event) == GST_EVENT_EOS); gst_event_unref (event); } while (!eos); buffer_count = gst_harness_buffers_received (h); GST_INFO ("Got %u buffers", buffer_count); if (num_expected >= 0) { fail_unless_equals_int (num_expected, buffer_count); } for (i = 0; i < buffer_count; ++i) { GstBuffer *buf; GstMapInfo map; guint16 soi, eoi; buf = gst_harness_pull (h); fail_unless (buf != NULL); fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ)); GST_MEMDUMP ("jpeg frame", map.data, map.size); fail_unless (map.size > 4); soi = GST_READ_UINT16_BE (map.data); fail_unless (soi == 0xffd8, "expected JPEG frame start FFD8 not %02X", soi); eoi = GST_READ_UINT16_BE (map.data + map.size - 2); fail_unless (eoi == 0xffd9, "expected JPEG frame end FFD9 not %02X", eoi); gst_buffer_unmap (buf, &map); gst_buffer_unref (buf); } gst_harness_teardown (h); }
static void check_buffer_equal (GstBuffer * buf, GstBuffer * expected) { GstMapInfo info_buf, info_expected; fail_if (buf == NULL); fail_if (expected == NULL); fail_unless (gst_buffer_map (buf, &info_buf, GST_MAP_READ)); fail_unless (gst_buffer_map (expected, &info_expected, GST_MAP_READ)); GST_LOG ("buffer: size %" G_GSIZE_FORMAT, info_buf.size); GST_LOG ("expected: size %" G_GSIZE_FORMAT, info_expected.size); GST_MEMDUMP ("buffer", info_buf.data, info_buf.size); GST_MEMDUMP ("expected", info_expected.data, info_expected.size); fail_unless_equals_uint64 (info_buf.size, info_expected.size); fail_unless_equals_int (memcmp (info_buf.data, info_expected.data, info_buf.size), 0); gst_buffer_unmap (buf, &info_buf); gst_buffer_unmap (expected, &info_expected); }
static void convert_line_uyvy (GstVideoVBIParser * parser, const guint8 * data) { guint i; guint8 *y = parser->work_data; guint8 *uv = y + parser->info.width; for (i = 0; i < parser->info.width - 3; i += 4) { *uv++ = data[(i / 4) * 4 + 0]; *y++ = data[(i / 4) * 4 + 1]; *uv++ = data[(i / 4) * 4 + 2]; *y++ = data[(i / 4) * 4 + 3]; } GST_MEMDUMP ("Converted line", parser->work_data, 128); }
static GstFlowReturn gst_jif_mux_chain (GstPad * pad, GstBuffer * buf) { GstJifMux *self = GST_JIF_MUX (GST_PAD_PARENT (pad)); GstFlowReturn fret = GST_FLOW_OK; if (GST_BUFFER_CAPS (buf) == NULL) { GST_WARNING_OBJECT (self, "Rejecting buffer without caps"); gst_buffer_unref (buf); return GST_FLOW_NOT_NEGOTIATED; } GST_MEMDUMP ("jpeg beg", GST_BUFFER_DATA (buf), 64); GST_MEMDUMP ("jpeg end", GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf) - 64, 64); /* we should have received a whole picture from SOI to EOI * build a list of markers */ if (gst_jif_mux_parse_image (self, buf)) { /* modify marker list */ if (gst_jif_mux_mangle_markers (self)) { /* the list was changed, remux */ GstBuffer *old = buf; fret = gst_jif_mux_recombine_image (self, &buf, old); gst_buffer_unref (old); } } /* free the marker list */ gst_jif_mux_reset (self); if (fret == GST_FLOW_OK) { fret = gst_pad_push (self->priv->srcpad, buf); } return fret; }
// // Expected synchronisation from caller. This method is not thread-safe! // bool PlayreadySession::playreadyProcessKey(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) { DRM_RESULT dr = DRM_SUCCESS; DRM_LICENSE_RESPONSE oLicenseResponse = {eUnknownProtocol, 0}; uint8_t *m_pbKeyMessageResponse = key->data(); uint32_t m_cbKeyMessageResponse = key->byteLength(); GST_MEMDUMP("response received :", key->data(), key->byteLength()); // The current state MUST be KEY_PENDING otherwise error out. ChkBOOL(m_eKeyState == KEY_PENDING, DRM_E_INVALIDARG); ChkArg(m_pbKeyMessageResponse != NULL && m_cbKeyMessageResponse > 0); ChkDR(Drm_LicenseAcq_ProcessResponse(m_poAppContext, DRM_PROCESS_LIC_RESPONSE_SIGNATURE_NOT_REQUIRED, NULL, NULL, const_cast<DRM_BYTE *>(m_pbKeyMessageResponse), m_cbKeyMessageResponse, &oLicenseResponse)); ChkDR(Drm_Reader_Bind(m_poAppContext, g_rgpdstrRights, NO_OF(g_rgpdstrRights), _PolicyCallback, NULL, &m_oDecryptContext)); m_key = key->buffer(); errorCode = 0; m_eKeyState = KEY_READY; GST_DEBUG("key processed, now ready for content decryption"); systemCode = dr; return true; ErrorExit: if (DRM_FAILED(dr)) { GST_ERROR("failed processing license response"); errorCode = MediaKeyError::MEDIA_KEYERR_CLIENT; m_eKeyState = KEY_ERROR; } return false; }
static GstCaps * typefind_data (const guint8 * data, gsize data_size, GstTypeFindProbability * prob) { GstBuffer *buf; GstCaps *caps; GST_MEMDUMP ("typefind data", data, data_size); buf = gst_buffer_new (); gst_buffer_append_memory (buf, gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, (guint8 *) data, data_size, 0, data_size, NULL, NULL)); GST_BUFFER_OFFSET (buf) = 0; caps = gst_type_find_helper_for_buffer (NULL, buf, prob); GST_INFO ("caps: %" GST_PTR_FORMAT ", probability=%u", caps, *prob); gst_buffer_unref (buf); return caps; }
/** * gst_codec_utils_h265_get_level: * @profile_tier_level: Pointer to the profile_tier_level structure * for the stream * @len: Length of the data available in @profile_tier_level. * * Converts the level indication (general_level_idc) in the stream's * profile_tier_level structure into a string. The profiel_tier_level is * expected to have the same format as for gst_codec_utils_h264_get_profile(). * * Returns: The level as a const string, or %NULL if there is an error. * * Since 1.4 */ const gchar * gst_codec_utils_h265_get_level (const guint8 * profile_tier_level, guint len) { g_return_val_if_fail (profile_tier_level != NULL, NULL); if (len < 12) return NULL; GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len); if (profile_tier_level[11] % 30 == 0) return digit_to_string (profile_tier_level[11] / 30); else { switch (profile_tier_level[11]) { case 63: return "2.1"; break; case 93: return "3.1"; break; case 123: return "4.1"; break; case 153: return "5.1"; break; case 156: return "5.2"; break; case 183: return "6.1"; break; case 186: return "6.2"; break; default: return NULL; } } }
// // Expected synchronisation from caller. This method is not thread-safe! // PassRefPtr<Uint8Array> DiscretixSession::dxdrmGenerateKeyRequest(Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode) { RefPtr<Uint8Array> result; EDxDrmStatus status = DxDrmClient_OpenDrmStreamFromData(&m_DxDrmStream, initData->data(), initData->byteLength()); GST_DEBUG("generating key request"); m_keyRequested = true; if (status != DX_SUCCESS) { GST_ERROR("failed to create DxDrmClient from initData (status: %d)", status); reportError(status); errorCode = MediaKeyError::MEDIA_KEYERR_CLIENT; } else { uint32_t challengeLength = MAX_CHALLENGE_LEN; unsigned char* challenge = static_cast<unsigned char*>(g_malloc0(challengeLength)); // Get challenge status = DxDrmStream_GetLicenseChallenge(m_DxDrmStream, challenge, &challengeLength); if (status != DX_SUCCESS) { GST_ERROR("failed to generate challenge request (status: %d)", status); errorCode = MediaKeyError::MEDIA_KEYERR_CLIENT; } else { // Get License URL destinationURL = static_cast<const char *>(DxDrmStream_GetTextAttribute(m_DxDrmStream, DX_ATTR_SILENT_URL, DX_ACTIVE_CONTENT)); GST_DEBUG("destination URL : %s", destinationURL.utf8().data()); GST_MEMDUMP("generated license request :", challenge, challengeLength); result = Uint8Array::create(challenge, challengeLength); errorCode = 0; } g_free(challenge); } systemCode = status; return result; }
/** * gst_codec_utils_h265_get_tier: * @profile_tier_level: Pointer to the profile_tier_level structure * for the stream. * @len: Length of the data available in @profile_tier_level. * * Converts the tier indication (general_tier_flag) in the stream's * profile_tier_level structure into a string. The profile_tier_level * is expected to have the same format as for gst_codec_utils_h264_get_profile(). * * Returns: The tier as a const string, or %NULL if there is an error. * * Since 1.4 */ const gchar * gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level, guint len) { const gchar *tier = NULL; gint tier_flag = 0; g_return_val_if_fail (profile_tier_level != NULL, NULL); if (len < 1) return NULL; GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len); tier_flag = (profile_tier_level[0] & 0x20) >> 5; if (tier_flag) tier = "high"; else tier = "main"; return tier; }
static void btic_midi_device_constructed (GObject * object) { const BtIcMidiDevice *const self = BTIC_MIDI_DEVICE (object); if (G_OBJECT_CLASS (btic_midi_device_parent_class)->constructed) G_OBJECT_CLASS (btic_midi_device_parent_class)->constructed (object); btic_learn_load_controller_map (BTIC_LEARN (self)); #if 0 // also see design/midi/rawmidi.c gint io; if ((io = open (self->priv->devnode, O_NONBLOCK | O_RDWR | O_SYNC)) > 0) { gchar data[17] = { 0, }; gsize ct; data[0] = MIDI_SYS_EX_START; data[1] = MIDI_NON_REALTIME; data[2] = 0x7f; // SysEx channel, set to "disregard" data[3] = 0x06; // General Information data[4] = 0x01; // Identity Request data[5] = MIDI_SYS_EX_END; GST_INFO ("send identity request to: %s", self->priv->devnode); if ((ct = write (io, data, 6)) < 6) goto done; do { ct = read (io, data, 15); } while (ct == -1); GST_MEMDUMP ("reply", (guint8 *) data, 15); // 5: manufacturer id (if 0, then id is next two bytes) // 6,7: family code // 8,9: model code // 10,11,12,13: version number done: close (io); } #endif }
static guint gst_mpeg_descriptor_parse_1 (guint8 * data, guint size) { guint8 tag; guint8 length; /* need at least 2 bytes for tag and length */ if (size < 2) return 0; tag = *data++; length = *data++; size -= 2; GST_DEBUG ("tag: 0x%02x, length: %d", tag, length); if (length > size) return 0; GST_MEMDUMP ("tag contents:", data, length); return length + 2; }
static gpointer _parse_atsc_vct (GstMpegtsSection * section) { GstMpegtsAtscVCT *vct = NULL; guint8 *data, *end, source_nb; guint32 tmp32; guint16 descriptors_loop_length, tmp16; guint i; GError *err = NULL; vct = g_slice_new0 (GstMpegtsAtscVCT); data = section->data; end = data + section->section_length; vct->transport_stream_id = section->subtable_extension; /* Skip already parsed data */ data += 8; /* minimum size */ if (end - data < 2 + 2 + 4) goto error; vct->protocol_version = *data; data += 1; source_nb = *data; data += 1; vct->sources = g_ptr_array_new_full (source_nb, (GDestroyNotify) _gst_mpegts_atsc_vct_source_free); for (i = 0; i < source_nb; i++) { GstMpegtsAtscVCTSource *source; /* minimum 32 bytes for a entry, 2 bytes second descriptor loop-length, 4 bytes crc */ if (end - data < 32 + 2 + 4) goto error; source = g_slice_new0 (GstMpegtsAtscVCTSource); g_ptr_array_add (vct->sources, source); source->short_name = g_convert ((gchar *) data, 14, "utf-8", "utf-16be", NULL, NULL, &err); if (err) { GST_WARNING ("Failed to convert VCT Source short_name to utf-8: %d %s", err->code, err->message); GST_MEMDUMP ("UTF-16 string", data, 14); g_error_free (err); } data += 14; tmp32 = GST_READ_UINT32_BE (data); source->major_channel_number = (tmp32 >> 18) & 0x03FF; source->minor_channel_number = (tmp32 >> 8) & 0x03FF; source->modulation_mode = tmp32 & 0xF; data += 4; source->carrier_frequency = GST_READ_UINT32_BE (data); data += 4; source->channel_TSID = GST_READ_UINT16_BE (data); data += 2; source->program_number = GST_READ_UINT16_BE (data); data += 2; tmp16 = GST_READ_UINT16_BE (data); source->ETM_location = (tmp16 >> 14) & 0x3; source->access_controlled = (tmp16 >> 13) & 0x1; source->hidden = (tmp16 >> 12) & 0x1; /* only used in CVCT */ source->path_select = (tmp16 >> 11) & 0x1; source->out_of_band = (tmp16 >> 10) & 0x1; source->hide_guide = (tmp16 >> 9) & 0x1; source->service_type = tmp16 & 0x3f; data += 2; source->source_id = GST_READ_UINT16_BE (data); data += 2; descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x03FF; data += 2; if (end - data < descriptors_loop_length + 6) goto error; source->descriptors = gst_mpegts_parse_descriptors (data, descriptors_loop_length); if (source->descriptors == NULL) goto error; data += descriptors_loop_length; } descriptors_loop_length = GST_READ_UINT16_BE (data) & 0x03FF; data += 2; if (end - data < descriptors_loop_length + 4) goto error; vct->descriptors = gst_mpegts_parse_descriptors (data, descriptors_loop_length); if (vct->descriptors == NULL) goto error; data += descriptors_loop_length; return (gpointer) vct; error: _gst_mpegts_atsc_vct_free (vct); return NULL; }
// // Expected synchronisation from caller. This method is not thread-safe! // RefPtr<Uint8Array> PlayreadySession::playreadyGenerateKeyRequest(Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) { RefPtr<Uint8Array> result; DRM_RESULT dr = DRM_SUCCESS; DRM_BYTE *pbChallenge = NULL; DRM_DWORD cbChallenge = 0; DRM_CHAR *pchSilentURL = NULL; DRM_DWORD cchSilentURL = 0; DRM_ANSI_STRING dastrCustomData = EMPTY_DRM_STRING; GST_DEBUG("generating key request"); GST_MEMDUMP("init data", initData->data(), initData->byteLength()); // The current state MUST be KEY_INIT otherwise error out. ChkBOOL(m_eKeyState == KEY_INIT, DRM_E_INVALIDARG); ChkDR(Drm_Content_SetProperty(m_poAppContext, DRM_CSP_AUTODETECT_HEADER, initData->data(), initData->byteLength())); GST_DEBUG("init data set on DRM context"); if (DRM_SUCCEEDED(Drm_Reader_Bind(m_poAppContext, g_rgpdstrRights, NO_OF(g_rgpdstrRights), _PolicyCallback, NULL, &m_oDecryptContext))) { GST_DEBUG("Play rights already acquired!"); m_eKeyState = KEY_READY; systemCode = dr; errorCode = 0; return nullptr; } GST_DEBUG("DRM reader bound"); // Try to figure out the size of the license acquisition // challenge to be returned. dr = Drm_LicenseAcq_GenerateChallenge(m_poAppContext, g_rgpdstrRights, NO_OF(g_rgpdstrRights), NULL, dastrCustomData.pszString, //m_pchCustomData, dastrCustomData.cchString, //m_cchCustomData, NULL, &cchSilentURL, NULL, NULL, pbChallenge, &cbChallenge); if (dr == DRM_E_BUFFERTOOSMALL) { if (cchSilentURL > 0) { ChkMem(pchSilentURL = (DRM_CHAR *)Oem_MemAlloc(cchSilentURL + 1)); ZEROMEM(pchSilentURL, cchSilentURL + 1); } // Allocate buffer that is sufficient to store the license acquisition // challenge. if (cbChallenge > 0) ChkMem(pbChallenge = (DRM_BYTE *)Oem_MemAlloc(cbChallenge)); dr = DRM_SUCCESS; } else { ChkDR(dr); GST_DEBUG("challenge generated"); } // Supply a buffer to receive the license acquisition challenge. ChkDR(Drm_LicenseAcq_GenerateChallenge(m_poAppContext, g_rgpdstrRights, NO_OF(g_rgpdstrRights), NULL, NULL, 0, pchSilentURL, &cchSilentURL, NULL, NULL, pbChallenge, &cbChallenge)); GST_MEMDUMP("generated license request :", pbChallenge, cbChallenge); result = Uint8Array::create(pbChallenge, cbChallenge); destinationURL = static_cast<const char *>(pchSilentURL); GST_DEBUG("destination URL : %s", destinationURL.utf8().data()); m_eKeyState = KEY_PENDING; systemCode = dr; errorCode = 0; SAFE_OEM_FREE(pbChallenge); SAFE_OEM_FREE(pchSilentURL); return result; ErrorExit: if (DRM_FAILED(dr)) { GST_DEBUG("DRM key generation failed"); errorCode = MediaKeyError::MEDIA_KEYERR_CLIENT; } return result; }
/** * validate_data: * @data: the data to validate * @len: the length of @data to validate * @payload: the payload if @data represents the header only * @payload_len: the len of the payload * * Checks if @data is a valid RTP packet. * * Returns: TRUE if @data is a valid RTP packet */ static gboolean validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len) { guint8 padding; guint8 csrc_count; guint header_len; guint8 version; g_return_val_if_fail (data != NULL, FALSE); header_len = GST_RTP_HEADER_LEN; if (G_UNLIKELY (len < header_len)) goto wrong_length; /* check version */ version = (data[0] & 0xc0); if (G_UNLIKELY (version != (GST_RTP_VERSION << 6))) goto wrong_version; /* calc header length with csrc */ csrc_count = (data[0] & 0x0f); header_len += csrc_count * sizeof (guint32); /* calc extension length when present. */ if (data[0] & 0x10) { guint8 *extpos; guint16 extlen; /* this points to the extenstion bits and header length */ extpos = &data[header_len]; /* skip the header and check that we have enough space */ header_len += 4; if (G_UNLIKELY (len < header_len)) goto wrong_length; /* skip id */ extpos += 2; /* read length as the number of 32 bits words */ extlen = GST_READ_UINT16_BE (extpos); header_len += extlen * sizeof (guint32); } /* check for padding */ if (data[0] & 0x20) { if (payload) padding = payload[payload_len - 1]; else padding = data[len - 1]; } else { padding = 0; } /* check if padding and header not bigger than packet length */ if (G_UNLIKELY (len < padding + header_len)) goto wrong_padding; return TRUE; /* ERRORS */ wrong_length: { GST_DEBUG ("len < header_len check failed (%d < %d)", len, header_len); goto dump_packet; } wrong_version: { GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION); goto dump_packet; } wrong_padding: { GST_DEBUG ("padding check failed (%d - %d < %d)", len, header_len, padding); goto dump_packet; } dump_packet: { GST_MEMDUMP ("buffer", data, len); return FALSE; } }
// // Expected synchronisation from caller. This method is not thread-safe! // bool DiscretixSession::dxdrmProcessKey(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) { GST_MEMDUMP("response received :", key->data(), key->byteLength()); bool isAckRequired; HDxResponseResult responseResult = nullptr; EDxDrmStatus status = DX_ERROR_CONTENT_NOT_RECOGNIZED; errorCode = 0; if (m_state == PHASE_INITIAL) { // Server replied to our license request status = DxDrmStream_ProcessLicenseResponse(m_DxDrmStream, key->data(), key->byteLength(), &responseResult, &isAckRequired); if (status == DX_SUCCESS) { // Create a deep copy of the key. m_key = key->buffer(); m_state = (isAckRequired ? PHASE_ACKNOWLEDGE : PHASE_PROVISIONED); GST_DEBUG("Acknowledgement required: %s", isAckRequired ? "yes" : "no"); } } else if (m_state == PHASE_ACKNOWLEDGE) { // Server replied to our license response acknowledge status = DxDrmClient_ProcessServerResponse(key->data(), key->byteLength(), DX_RESPONSE_LICENSE_ACK, &responseResult, &isAckRequired); if (status == DX_SUCCESS) { // Create a deep copy of the key. m_key = key->buffer(); m_state = (isAckRequired ? PHASE_ACKNOWLEDGE : PHASE_PROVISIONED); if (m_state == PHASE_ACKNOWLEDGE) GST_WARNING("Acknowledging an Ack. Strange situation."); } } else GST_WARNING("Unexpected call. We are already provisioned"); if (status != DX_SUCCESS) { GST_ERROR("failed processing license response (status: %d)", status); errorCode = MediaKeyError::MEDIA_KEYERR_CLIENT; } else if (m_state == PHASE_PROVISIONED) { status = DxDrmStream_SetIntent(m_DxDrmStream, DX_INTENT_AUTO_PLAY, DX_AUTO_NO_UI); if (status != DX_SUCCESS) GST_ERROR("opening stream failed because there are no rights (license) to play the content (status: %d)", status); else { GST_INFO("playback rights found"); /* starting consumption of the file - notifying the drm that the file is being used */ status = DxDrmFile_HandleConsumptionEvent(m_DxDrmStream, DX_EVENT_START); if (status != DX_SUCCESS) GST_ERROR("Content consumption failed"); else { GST_INFO("Stream was opened and is ready for playback"); m_ready = true; } } } else if (m_state == PHASE_ACKNOWLEDGE) { uint32_t challengeLength = MAX_CHALLENGE_LEN; unsigned char* challenge = static_cast<unsigned char*>(g_malloc0(challengeLength)); status = DxDrmClient_GetLicenseAcq_GenerateAck(&responseResult, challenge, &challengeLength); if (status != DX_SUCCESS) GST_ERROR("failed generating license ack challenge (status: %d, response result %p)", status, responseResult); GST_MEMDUMP("generated license ack request :", challenge, challengeLength); nextMessage = Uint8Array::create(challenge, challengeLength); g_free(challenge); } systemCode = status; return (status == DX_SUCCESS); }
static GstFlowReturn gst_vdp_h264_dec_parse_data (GstBaseVideoDecoder * base_video_decoder, GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame) { GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder); GstBitReader reader; GstNalUnit nal_unit; guint8 forbidden_zero_bit; guint8 *data; guint size; gint i; GstFlowReturn ret = GST_FLOW_OK; GST_MEMDUMP ("data", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); gst_bit_reader_init_from_buffer (&reader, buf); if (gst_bit_reader_get_remaining (&reader) < h264_dec->nal_length_size * 8 + 7) goto invalid_packet; /* skip nal_length or sync code */ gst_bit_reader_skip_unchecked (&reader, h264_dec->nal_length_size * 8); forbidden_zero_bit = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1); if (forbidden_zero_bit != 0) { GST_WARNING ("forbidden_zero_bit != 0"); return GST_FLOW_ERROR; } nal_unit.ref_idc = gst_bit_reader_get_bits_uint16_unchecked (&reader, 2); GST_DEBUG ("nal_ref_idc: %u", nal_unit.ref_idc); /* read nal_unit_type */ nal_unit.type = gst_bit_reader_get_bits_uint16_unchecked (&reader, 5); GST_DEBUG ("nal_unit_type: %u", nal_unit.type); if (nal_unit.type == 14 || nal_unit.type == 20) { if (!gst_bit_reader_skip (&reader, 24)) goto invalid_packet; } nal_unit.IdrPicFlag = (nal_unit.type == 5 ? 1 : 0); data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; size = gst_bit_reader_get_remaining (&reader) / 8; i = size - 1; while ((gint) size > 0 && data[i] == 0x00) { size--; i--; } if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) { if (nal_unit.type == GST_NAL_SPS || nal_unit.type == GST_NAL_PPS || nal_unit.type == GST_NAL_SEI || nal_unit.type == GST_NAL_AU_DELIMITER || (nal_unit.type >= 14 && nal_unit.type <= 18)) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, &frame); } if (nal_unit.type >= GST_NAL_SLICE && nal_unit.type <= GST_NAL_SLICE_IDR) { GstH264Slice slice; if (!gst_h264_parser_parse_slice_header (h264_dec->parser, &slice, data, size, nal_unit)) goto invalid_packet; if (slice.redundant_pic_cnt == 0) { if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) { GstH264Slice *p_slice; guint8 pic_order_cnt_type, p_pic_order_cnt_type; gboolean finish_frame = FALSE; p_slice = &(GST_H264_FRAME_CAST (frame)->slice_hdr); pic_order_cnt_type = slice.picture->sequence->pic_order_cnt_type; p_pic_order_cnt_type = p_slice->picture->sequence->pic_order_cnt_type; if (slice.frame_num != p_slice->frame_num) finish_frame = TRUE; else if (slice.picture != p_slice->picture) finish_frame = TRUE; else if (slice.bottom_field_flag != p_slice->bottom_field_flag) finish_frame = TRUE; else if (nal_unit.ref_idc != p_slice->nal_unit.ref_idc && (nal_unit.ref_idc == 0 || p_slice->nal_unit.ref_idc == 0)) finish_frame = TRUE; else if ((pic_order_cnt_type == 0 && p_pic_order_cnt_type == 0) && (slice.pic_order_cnt_lsb != p_slice->pic_order_cnt_lsb || slice.delta_pic_order_cnt_bottom != p_slice->delta_pic_order_cnt_bottom)) finish_frame = TRUE; else if ((p_pic_order_cnt_type == 1 && p_pic_order_cnt_type == 1) && (slice.delta_pic_order_cnt[0] != p_slice->delta_pic_order_cnt[0] || slice.delta_pic_order_cnt[1] != p_slice->delta_pic_order_cnt[1])) finish_frame = TRUE; if (finish_frame) ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE, &frame); } if (!GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) { if (GST_H264_IS_I_SLICE (slice.type) || GST_H264_IS_SI_SLICE (slice.type)) GST_VIDEO_FRAME_FLAG_SET (frame, GST_VIDEO_FRAME_FLAG_KEYFRAME); GST_H264_FRAME_CAST (frame)->slice_hdr = slice; GST_VIDEO_FRAME_FLAG_SET (frame, GST_H264_FRAME_GOT_PRIMARY); } } gst_h264_frame_add_slice ((GstH264Frame *) frame, buf); } if (nal_unit.type == GST_NAL_SPS) { if (!gst_h264_parser_parse_sequence (h264_dec->parser, data, size)) goto invalid_packet; } if (nal_unit.type == GST_NAL_PPS) { if (!gst_h264_parser_parse_picture (h264_dec->parser, data, size)) goto invalid_packet; } gst_buffer_unref (buf); return ret; invalid_packet: GST_WARNING ("Invalid packet size!"); gst_buffer_unref (buf); return GST_FLOW_OK; }
static gboolean gst_vdp_h264_dec_set_sink_caps (GstBaseVideoDecoder * base_video_decoder, GstCaps * caps) { GstVdpH264Dec *h264_dec; GstStructure *structure; const GValue *value; h264_dec = GST_VDP_H264_DEC (base_video_decoder); structure = gst_caps_get_structure (caps, 0); /* packetized video has a codec_data */ if ((value = gst_structure_get_value (structure, "codec_data"))) { GstBuffer *buf; GstBitReader reader; guint8 version; guint8 n_sps, n_pps; gint i; GST_DEBUG_OBJECT (h264_dec, "have packetized h264"); h264_dec->packetized = TRUE; buf = gst_value_get_buffer (value); GST_MEMDUMP ("avcC:", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); /* parse the avcC data */ if (GST_BUFFER_SIZE (buf) < 7) { GST_ERROR_OBJECT (h264_dec, "avcC size %u < 7", GST_BUFFER_SIZE (buf)); return FALSE; } gst_bit_reader_init_from_buffer (&reader, buf); READ_UINT8 (&reader, version, 8); if (version != 1) return FALSE; SKIP (&reader, 30); READ_UINT8 (&reader, h264_dec->nal_length_size, 2); h264_dec->nal_length_size += 1; GST_DEBUG_OBJECT (h264_dec, "nal length %u", h264_dec->nal_length_size); SKIP (&reader, 3); READ_UINT8 (&reader, n_sps, 5); for (i = 0; i < n_sps; i++) { guint16 sps_length; guint8 *data; READ_UINT16 (&reader, sps_length, 16); sps_length -= 1; SKIP (&reader, 8); data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; if (!gst_h264_parser_parse_sequence (h264_dec->parser, data, sps_length)) return FALSE; SKIP (&reader, sps_length * 8); } READ_UINT8 (&reader, n_pps, 8); for (i = 0; i < n_pps; i++) { guint16 pps_length; guint8 *data; READ_UINT16 (&reader, pps_length, 16); pps_length -= 1; SKIP (&reader, 8); data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; if (!gst_h264_parser_parse_picture (h264_dec->parser, data, pps_length)) return FALSE; SKIP (&reader, pps_length * 8); } } return TRUE; }
static GstBuffer * gst_rtp_qdm2_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) { GstRtpQDM2Depay *rtpqdm2depay; GstBuffer *outbuf; guint16 seq; rtpqdm2depay = GST_RTP_QDM2_DEPAY (depayload); { gint payload_len; guint8 *payload; guint avail; guint pos = 0; payload_len = gst_rtp_buffer_get_payload_len (buf); if (payload_len < 3) goto bad_packet; payload = gst_rtp_buffer_get_payload (buf); seq = gst_rtp_buffer_get_seq (buf); if (G_UNLIKELY (seq != rtpqdm2depay->nextseq)) { GST_DEBUG ("GAP in sequence number, Resetting data !"); /* Flush previous data */ flush_data (rtpqdm2depay); /* And store new timestamp */ rtpqdm2depay->ptimestamp = rtpqdm2depay->timestamp; rtpqdm2depay->timestamp = GST_BUFFER_TIMESTAMP (buf); /* And that previous data will be pushed at the bottom */ } rtpqdm2depay->nextseq = seq + 1; GST_DEBUG ("Payload size %d 0x%x sequence:%d", payload_len, payload_len, seq); GST_MEMDUMP ("Incoming payload", payload, payload_len); while (pos < payload_len) { switch (payload[pos]) { case 0x80:{ GST_DEBUG ("Unrecognized 0x80 marker, skipping 12 bytes"); pos += 12; } break; case 0xff: /* HEADERS */ GST_DEBUG ("Headers"); /* Store the incoming timestamp */ rtpqdm2depay->ptimestamp = rtpqdm2depay->timestamp; rtpqdm2depay->timestamp = GST_BUFFER_TIMESTAMP (buf); /* flush the internal data if needed */ flush_data (rtpqdm2depay); if (G_UNLIKELY (!rtpqdm2depay->configured)) { guint8 *ourdata; GstBuffer *codecdata; GstCaps *caps; /* First bytes are unknown */ GST_MEMDUMP ("Header", payload + pos, 32); ourdata = payload + pos + 10; pos += 10; rtpqdm2depay->channs = GST_READ_UINT32_BE (payload + pos + 4); rtpqdm2depay->samplerate = GST_READ_UINT32_BE (payload + pos + 8); rtpqdm2depay->bitrate = GST_READ_UINT32_BE (payload + pos + 12); rtpqdm2depay->blocksize = GST_READ_UINT32_BE (payload + pos + 16); rtpqdm2depay->framesize = GST_READ_UINT32_BE (payload + pos + 20); rtpqdm2depay->packetsize = GST_READ_UINT32_BE (payload + pos + 24); /* 16 bit empty block (0x02 0x00) */ pos += 30; GST_DEBUG ("channs:%d, samplerate:%d, bitrate:%d, blocksize:%d, framesize:%d, packetsize:%d", rtpqdm2depay->channs, rtpqdm2depay->samplerate, rtpqdm2depay->bitrate, rtpqdm2depay->blocksize, rtpqdm2depay->framesize, rtpqdm2depay->packetsize); /* Caps */ codecdata = gst_buffer_new_and_alloc (48); memcpy (GST_BUFFER_DATA (codecdata), headheader, 20); memcpy (GST_BUFFER_DATA (codecdata) + 20, ourdata, 28); caps = gst_caps_new_simple ("audio/x-qdm2", "samplesize", G_TYPE_INT, 16, "rate", G_TYPE_INT, rtpqdm2depay->samplerate, "channels", G_TYPE_INT, rtpqdm2depay->channs, "codec_data", GST_TYPE_BUFFER, codecdata, NULL); gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), caps); gst_caps_unref (caps); rtpqdm2depay->configured = TRUE; } else { GST_DEBUG ("Already configured, skipping headers"); pos += 40; } break; default:{ /* Shuffled packet contents */ guint packetid = payload[pos++]; guint packettype = payload[pos++]; guint packlen = payload[pos++]; guint hsize = 2; GST_DEBUG ("Packet id:%d, type:0x%x, len:%d", packetid, packettype, packlen); /* Packets bigger than 0xff bytes have a type with the high bit set */ if (G_UNLIKELY (packettype & 0x80)) { packettype &= 0x7f; packlen <<= 8; packlen |= payload[pos++]; hsize = 3; GST_DEBUG ("Packet id:%d, type:0x%x, len:%d", packetid, packettype, packlen); } if (packettype > 0x7f) { GST_ERROR ("HOUSTON WE HAVE A PROBLEM !!!!"); } add_packet (rtpqdm2depay, packetid, packlen + hsize, payload + pos - hsize); pos += packlen; } } } GST_DEBUG ("final pos %d", pos); avail = gst_adapter_available (rtpqdm2depay->adapter); if (G_UNLIKELY (avail)) { GST_DEBUG ("Pushing out %d bytes of collected data", avail); outbuf = gst_adapter_take_buffer (rtpqdm2depay->adapter, avail); GST_BUFFER_TIMESTAMP (outbuf) = rtpqdm2depay->ptimestamp; GST_DEBUG ("Outgoing buffer timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (rtpqdm2depay->ptimestamp)); return outbuf; } } return NULL; /* ERRORS */ bad_packet: { GST_ELEMENT_WARNING (rtpqdm2depay, STREAM, DECODE, (NULL), ("Packet was too short")); return NULL; } }
static void flush_data (GstRtpQDM2Depay * depay) { guint i; guint avail; if ((avail = gst_adapter_available (depay->adapter))) gst_adapter_flush (depay->adapter, avail); GST_DEBUG ("Flushing %d packets", depay->nbpackets); for (i = 0; depay->packets[i]; i++) { QDM2Packet *pack = depay->packets[i]; guint32 crc = 0; int i = 0; GstBuffer *buf; guint8 *data; /* CRC is the sum of everything (including first bytes) */ data = pack->data; if (G_UNLIKELY (data == NULL)) continue; /* If the packet size is bigger than 0xff, we need 2 bytes to store the size */ if (depay->packetsize > 0xff) { /* Expanded size 0x02 | 0x80 */ data[0] = 0x82; GST_WRITE_UINT16_BE (data + 1, depay->packetsize - 3); } else { data[0] = 0x2; data[1] = depay->packetsize - 2; } /* Calculate CRC */ for (; i < depay->packetsize; i++) crc += data[i]; GST_DEBUG ("CRC is 0x%x", crc); /* Write CRC */ if (depay->packetsize > 0xff) GST_WRITE_UINT16_BE (data + 3, crc); else GST_WRITE_UINT16_BE (data + 2, crc); GST_MEMDUMP ("Extracted packet", data, depay->packetsize); buf = gst_buffer_new (); GST_BUFFER_DATA (buf) = data; GST_BUFFER_MALLOCDATA (buf) = data; GST_BUFFER_SIZE (buf) = depay->packetsize; gst_adapter_push (depay->adapter, buf); if (pack->data) { pack->data = NULL; } } }
/** * gst_mpegts_parse_descriptors: * @buffer: (transfer none): descriptors to parse * @buf_len: Size of @buffer * * Parses the descriptors present in @buffer and returns them as an * array. * * Note: The data provided in @buffer will not be copied. * * Returns: (transfer full) (element-type GstMpegtsDescriptor): an * array of the parsed descriptors or %NULL if there was an error. * Release with #g_array_unref when done with it. */ GPtrArray * gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len) { GPtrArray *res; guint8 length; guint8 *data; guint i, nb_desc = 0; /* fast-path */ if (buf_len == 0) return g_ptr_array_new (); data = buffer; GST_MEMDUMP ("Full descriptor array", buffer, buf_len); while (data - buffer < buf_len) { data++; /* skip tag */ length = *data++; if (data - buffer > buf_len) { GST_WARNING ("invalid descriptor length %d now at %d max %" G_GSIZE_FORMAT, length, (gint) (data - buffer), buf_len); return NULL; } data += length; nb_desc++; } GST_DEBUG ("Saw %d descriptors, read %" G_GSIZE_FORMAT " bytes", nb_desc, (gsize) (data - buffer)); if (data - buffer != buf_len) { GST_WARNING ("descriptors size %d expected %" G_GSIZE_FORMAT, (gint) (data - buffer), buf_len); return NULL; } res = g_ptr_array_new_full (nb_desc + 1, (GDestroyNotify) gst_mpegts_descriptor_free); data = buffer; for (i = 0; i < nb_desc; i++) { GstMpegtsDescriptor *desc = g_slice_new0 (GstMpegtsDescriptor); desc->data = data; desc->tag = *data++; desc->length = *data++; /* Copy the data now that we known the size */ desc->data = g_memdup (desc->data, desc->length + 2); GST_LOG ("descriptor 0x%02x length:%d", desc->tag, desc->length); GST_MEMDUMP ("descriptor", desc->data + 2, desc->length); /* extended descriptors */ if (G_UNLIKELY (desc->tag == 0x7f)) desc->tag_extension = *data; data += desc->length; /* Set the descriptor in the array */ g_ptr_array_index (res, i) = desc; } res->len = nb_desc; return res; }
gboolean id3demux_id3v2_parse_frame (ID3TagsWorking * work) { const gchar *tag_name; gboolean result = FALSE; gint i; guint8 *frame_data = work->hdr.frame_data; guint frame_data_size = work->cur_frame_size; gchar *tag_str = NULL; GArray *tag_fields = NULL; guint8 *uu_data = NULL; #ifdef HAVE_ZLIB guint8 *uncompressed_data = NULL; #endif /* Check that the frame id is valid */ for (i = 0; i < 5 && work->frame_id[i] != '\0'; i++) { if (!g_ascii_isalnum (work->frame_id[i])) { GST_DEBUG ("Encountered invalid frame_id"); return FALSE; } } /* Can't handle encrypted frames right now (in case we ever do, we'll have * to do the decryption after the un-unsynchronisation and decompression, * not here) */ if (work->frame_flags & ID3V2_FRAME_FORMAT_ENCRYPTION) { GST_WARNING ("Encrypted frames are not supported"); return FALSE; } tag_name = gst_tag_from_id3_tag (work->frame_id); if (tag_name == NULL && strncmp (work->frame_id, "RVA2", 4) != 0 && strncmp (work->frame_id, "TXXX", 4) != 0 && strncmp (work->frame_id, "TDAT", 4) != 0 && strncmp (work->frame_id, "UFID", 4) != 0) { return FALSE; } if (work->frame_flags & (ID3V2_FRAME_FORMAT_COMPRESSION | ID3V2_FRAME_FORMAT_DATA_LENGTH_INDICATOR)) { if (work->hdr.frame_data_size <= 4) return FALSE; if (ID3V2_VER_MAJOR (work->hdr.version) == 3) { work->parse_size = GST_READ_UINT32_BE (frame_data); } else { work->parse_size = read_synch_uint (frame_data, 4); } frame_data += 4; frame_data_size -= 4; GST_LOG ("Un-unsynced data size %d (of %d)", work->parse_size, frame_data_size); if (work->parse_size > frame_data_size) { GST_WARNING ("ID3v2 frame %s data has invalid size %d (>%d)", work->frame_id, work->parse_size, frame_data_size); return FALSE; } } /* in v2.3 the frame sizes are not syncsafe, so the entire tag had to be * unsynced. In v2.4 the frame sizes are syncsafe so it's just the frame * data that needs un-unsyncing, but not the frame headers. */ if (ID3V2_VER_MAJOR (work->hdr.version) == 4) { if ((work->hdr.flags & ID3V2_HDR_FLAG_UNSYNC) != 0 || ((work->frame_flags & ID3V2_FRAME_FORMAT_UNSYNCHRONISATION) != 0)) { GST_DEBUG ("Un-unsyncing frame %s", work->frame_id); uu_data = id3demux_ununsync_data (frame_data, &frame_data_size); frame_data = uu_data; GST_MEMDUMP ("ID3v2 frame (un-unsyced)", frame_data, frame_data_size); } } work->parse_size = frame_data_size; if (work->frame_flags & ID3V2_FRAME_FORMAT_COMPRESSION) { #ifdef HAVE_ZLIB uLongf destSize = work->parse_size; Bytef *dest, *src; uncompressed_data = g_malloc (work->parse_size); dest = (Bytef *) uncompressed_data; src = (Bytef *) frame_data; if (uncompress (dest, &destSize, src, frame_data_size) != Z_OK) { g_free (uncompressed_data); g_free (uu_data); return FALSE; } if (destSize != work->parse_size) { GST_WARNING ("Decompressing ID3v2 frame %s did not produce expected size %d bytes (got %lu)", tag_name, work->parse_size, destSize); g_free (uncompressed_data); g_free (uu_data); return FALSE; } work->parse_data = uncompressed_data; #else GST_WARNING ("Compressed ID3v2 tag frame could not be decompressed" " because gstid3demux was compiled without zlib support"); g_free (uu_data); return FALSE; #endif } else { work->parse_data = frame_data; } if (work->frame_id[0] == 'T') { if (strcmp (work->frame_id, "TDAT") == 0) { parse_obsolete_tdat_frame (work); result = TRUE; } else if (strcmp (work->frame_id, "TXXX") == 0) { /* Handle user text frame */ tag_str = parse_user_text_identification_frame (work, &tag_name); } else { /* Text identification frame */ tag_fields = parse_text_identification_frame (work); } } else if (work->frame_id[0] == 'W' && strcmp (work->frame_id, "WXXX") != 0) { /* URL link frame: ISO-8859-1 encoded, one frame per tag */ tag_str = parse_url_link_frame (work, &tag_name); } else if (!strcmp (work->frame_id, "COMM")) { /* Comment */ result = parse_comment_frame (work); } else if (!strcmp (work->frame_id, "APIC")) { /* Attached picture */ result = parse_picture_frame (work); } else if (!strcmp (work->frame_id, "RVA2")) { /* Relative volume */ result = parse_relative_volume_adjustment_two (work); } else if (!strcmp (work->frame_id, "UFID")) { /* Unique file identifier */ tag_str = parse_unique_file_identifier (work, &tag_name); } #ifdef HAVE_ZLIB if (work->frame_flags & ID3V2_FRAME_FORMAT_COMPRESSION) { g_free (uncompressed_data); uncompressed_data = NULL; work->parse_data = frame_data; } #endif if (tag_str != NULL) { /* g_print ("Tag %s value %s\n", tag_name, tag_str); */ result = id3v2_tag_to_taglist (work, tag_name, tag_str); g_free (tag_str); } if (tag_fields != NULL) { if (strcmp (work->frame_id, "TCON") == 0) { /* Genre strings need special treatment */ result |= id3v2_genre_fields_to_taglist (work, tag_name, tag_fields); } else { gint t; for (t = 0; t < tag_fields->len; t++) { tag_str = g_array_index (tag_fields, gchar *, t); if (tag_str != NULL && tag_str[0] != '\0') result |= id3v2_tag_to_taglist (work, tag_name, tag_str); } } free_tag_strings (tag_fields); } g_free (uu_data); return result; }
static void check_1x1_buffer (GstBuffer * buf, GstCaps * caps) { GstVideoInfo info; GstVideoFrame frame; /* the exact values we check for come from videotestsrc */ static const guint yuv_values[] = { 81, 90, 240, 255 }; static const guint rgb_values[] = { 0xff, 0, 0, 255 }; static const guint gray8_values[] = { 0x51 }; static const guint gray16_values[] = { 0x5151 }; const guint *values; guint i; const GstVideoFormatInfo *finfo; fail_unless (buf != NULL); fail_unless (caps != NULL); fail_unless (gst_video_info_from_caps (&info, caps)); fail_unless (gst_video_frame_map (&frame, &info, buf, GST_MAP_READ)); finfo = info.finfo; if (GST_VIDEO_INFO_IS_YUV (&info)) values = yuv_values; else if (GST_VIDEO_INFO_IS_GRAY (&info)) if (GST_VIDEO_FORMAT_INFO_BITS (finfo) == 8) values = gray8_values; else values = gray16_values; else values = rgb_values; GST_MEMDUMP ("buffer", GST_VIDEO_FRAME_PLANE_DATA (&frame, 0), 8); for (i = 0; i < GST_VIDEO_FRAME_N_COMPONENTS (&frame); i++) { guint8 *data = GST_VIDEO_FRAME_COMP_DATA (&frame, i); GST_DEBUG ("W: %d", GST_VIDEO_FORMAT_INFO_W_SUB (finfo, i)); GST_DEBUG ("H: %d", GST_VIDEO_FORMAT_INFO_H_SUB (finfo, i)); if (GST_VIDEO_FORMAT_INFO_W_SUB (finfo, i) >= GST_VIDEO_FRAME_WIDTH (&frame)) continue; if (GST_VIDEO_FORMAT_INFO_H_SUB (finfo, i) >= GST_VIDEO_FRAME_HEIGHT (&frame)) continue; if (GST_VIDEO_FORMAT_INFO_BITS (finfo) == 8) { fail_unless_equals_int (data[0], values[i]); } else if (GST_VIDEO_FORMAT_INFO_BITS (finfo) == 16) { guint16 pixels, val; gint depth; if (GST_VIDEO_FORMAT_INFO_IS_LE (finfo)) pixels = GST_READ_UINT16_LE (data); else pixels = GST_READ_UINT16_BE (data); depth = GST_VIDEO_FORMAT_INFO_DEPTH (finfo, i); val = pixels >> GST_VIDEO_FORMAT_INFO_SHIFT (finfo, i); val = val & ((1 << depth) - 1); GST_DEBUG ("val %08x %d : %d", pixels, i, val); if (depth <= 8) { fail_unless_equals_int (val, values[i] >> (8 - depth)); } else {