626 *
627 * Returns: %TRUE if duration is available.
628 */
629 static gboolean
630 gst_aiff_parse_calculate_duration (GstAiffParse * aiff)
631 {
632 if (aiff->duration > 0)
633 return TRUE;
634
635 if (aiff->datasize > 0 && aiff->bps > 0) {
636 aiff->duration =
637 gst_util_uint64_scale_ceil (aiff->datasize, GST_SECOND,
638 (guint64) aiff->bps);
639 GST_INFO_OBJECT (aiff, "Got duration %" GST_TIME_FORMAT,
640 GST_TIME_ARGS (aiff->duration));
641 return TRUE;
642 }
643 return FALSE;
644 }
645
646 static void
647 gst_aiff_parse_ignore_chunk (GstAiffParse * aiff, guint32 tag, guint32 size)
648 {
649 #ifdef GSTREAMER_LITE
650 guint64 flush;
651 #else
652 guint flush;
653 #endif
654
655 if (aiff->streaming) {
656 if (!gst_aiff_parse_peek_chunk (aiff, &tag, &size))
657 return;
658 }
659 GST_WARNING_OBJECT (aiff, "Ignoring tag %" GST_FOURCC_FORMAT,
660 GST_FOURCC_ARGS (tag));
661 #ifdef GSTREAMER_LITE
662 flush = 8 + (((guint64)size + 1) & ~1);
663 #else
664 flush = 8 + ((size + 1) & ~1);
665 #endif
666 aiff->offset += flush;
667 if (aiff->streaming) {
668 gst_adapter_flush (aiff->adapter, flush);
669 }
670 }
671
672 static double
673 gst_aiff_parse_read_IEEE80 (guint8 * buf)
674 {
675 int s = buf[0] & 0xff;
676 int e = ((buf[0] & 0x7f) << 8) | (buf[1] & 0xff);
677 double f = ((unsigned long) (buf[2] & 0xff) << 24) |
678 ((buf[3] & 0xff) << 16) | ((buf[4] & 0xff) << 8) | (buf[5] & 0xff);
679
680 if (e == 32767) {
681 if (buf[2] & 0x80)
682 return HUGE_VAL; /* Really NaN, but this won't happen in reality */
683 else {
684 if (s)
685 return -HUGE_VAL;
686 else
687 return HUGE_VAL;
688 }
689 }
1107 }
1108
1109 GST_LOG_OBJECT (aiff, "ID3 chunk of size %" G_GSIZE_FORMAT,
1110 gst_buffer_get_size (buf));
1111
1112 tags = gst_tag_list_from_id3v2_tag (buf);
1113 gst_buffer_unref (buf);
1114
1115 GST_INFO_OBJECT (aiff, "ID3 tags: %" GST_PTR_FORMAT, tags);
1116
1117 if (aiff->tags == NULL) {
1118 aiff->tags = tags;
1119 } else {
1120 gst_tag_list_insert (aiff->tags, tags, GST_TAG_MERGE_APPEND);
1121 gst_tag_list_unref (tags);
1122 }
1123 break;
1124 }
1125 case GST_MAKE_FOURCC ('C', 'H', 'A', 'N'):{
1126 GST_FIXME_OBJECT (aiff, "Handle CHAN chunk with channel layouts");
1127 gst_aiff_parse_ignore_chunk (aiff, tag, size);
1128 break;
1129 }
1130 default:
1131 gst_aiff_parse_ignore_chunk (aiff, tag, size);
1132 }
1133
1134 buf = NULL;
1135
1136 if (upstream_size && (aiff->offset >= upstream_size)) {
1137 /* Now we have gone through the whole file */
1138 done = TRUE;
1139 }
1140 }
1141
1142 /* We read all the chunks (in pull mode) or reached the SSND chunk
1143 * (in push mode). We must have both COMM and SSND now; error out
1144 * otherwise.
1145 */
1146 if (!aiff->got_comm) {
1147 GST_WARNING_OBJECT (aiff, "Failed to find COMM chunk");
1148 goto no_header;
1149 }
1150 if (!gotdata) {
1151 GST_WARNING_OBJECT (aiff, "Failed to find SSND chunk");
|
626 *
627 * Returns: %TRUE if duration is available.
628 */
629 static gboolean
630 gst_aiff_parse_calculate_duration (GstAiffParse * aiff)
631 {
632 if (aiff->duration > 0)
633 return TRUE;
634
635 if (aiff->datasize > 0 && aiff->bps > 0) {
636 aiff->duration =
637 gst_util_uint64_scale_ceil (aiff->datasize, GST_SECOND,
638 (guint64) aiff->bps);
639 GST_INFO_OBJECT (aiff, "Got duration %" GST_TIME_FORMAT,
640 GST_TIME_ARGS (aiff->duration));
641 return TRUE;
642 }
643 return FALSE;
644 }
645
646 #ifdef GSTREAMER_LITE
647 static gboolean
648 #else
649 static void
650 #endif
651 gst_aiff_parse_ignore_chunk (GstAiffParse * aiff, guint32 tag, guint32 size)
652 {
653 #ifdef GSTREAMER_LITE
654 guint64 flush;
655 #else
656 guint flush;
657 #endif
658
659 if (aiff->streaming) {
660 if (!gst_aiff_parse_peek_chunk (aiff, &tag, &size))
661 #ifdef GSTREAMER_LITE
662 return FALSE;
663 #else
664 return;
665 #endif
666 }
667 GST_WARNING_OBJECT (aiff, "Ignoring tag %" GST_FOURCC_FORMAT,
668 GST_FOURCC_ARGS (tag));
669 #ifdef GSTREAMER_LITE
670 flush = 8 + (((guint64)size + 1) & ~1);
671 #else
672 flush = 8 + ((size + 1) & ~1);
673 #endif
674 aiff->offset += flush;
675 if (aiff->streaming) {
676 gst_adapter_flush (aiff->adapter, flush);
677 }
678
679 #ifdef GSTREAMER_LITE
680 return TRUE;
681 #endif
682 }
683
684 static double
685 gst_aiff_parse_read_IEEE80 (guint8 * buf)
686 {
687 int s = buf[0] & 0xff;
688 int e = ((buf[0] & 0x7f) << 8) | (buf[1] & 0xff);
689 double f = ((unsigned long) (buf[2] & 0xff) << 24) |
690 ((buf[3] & 0xff) << 16) | ((buf[4] & 0xff) << 8) | (buf[5] & 0xff);
691
692 if (e == 32767) {
693 if (buf[2] & 0x80)
694 return HUGE_VAL; /* Really NaN, but this won't happen in reality */
695 else {
696 if (s)
697 return -HUGE_VAL;
698 else
699 return HUGE_VAL;
700 }
701 }
1119 }
1120
1121 GST_LOG_OBJECT (aiff, "ID3 chunk of size %" G_GSIZE_FORMAT,
1122 gst_buffer_get_size (buf));
1123
1124 tags = gst_tag_list_from_id3v2_tag (buf);
1125 gst_buffer_unref (buf);
1126
1127 GST_INFO_OBJECT (aiff, "ID3 tags: %" GST_PTR_FORMAT, tags);
1128
1129 if (aiff->tags == NULL) {
1130 aiff->tags = tags;
1131 } else {
1132 gst_tag_list_insert (aiff->tags, tags, GST_TAG_MERGE_APPEND);
1133 gst_tag_list_unref (tags);
1134 }
1135 break;
1136 }
1137 case GST_MAKE_FOURCC ('C', 'H', 'A', 'N'):{
1138 GST_FIXME_OBJECT (aiff, "Handle CHAN chunk with channel layouts");
1139 #ifdef GSTREAMER_LITE
1140 if (!gst_aiff_parse_ignore_chunk (aiff, tag, size)) {
1141 return GST_FLOW_OK;
1142 }
1143 #else
1144 gst_aiff_parse_ignore_chunk (aiff, tag, size);
1145 #endif
1146 break;
1147 }
1148 default:
1149 #ifdef GSTREAMER_LITE
1150 if (!gst_aiff_parse_ignore_chunk (aiff, tag, size)) {
1151 return GST_FLOW_OK;
1152 }
1153 #else
1154 gst_aiff_parse_ignore_chunk (aiff, tag, size);
1155 #endif
1156 }
1157
1158 buf = NULL;
1159
1160 if (upstream_size && (aiff->offset >= upstream_size)) {
1161 /* Now we have gone through the whole file */
1162 done = TRUE;
1163 }
1164 }
1165
1166 /* We read all the chunks (in pull mode) or reached the SSND chunk
1167 * (in push mode). We must have both COMM and SSND now; error out
1168 * otherwise.
1169 */
1170 if (!aiff->got_comm) {
1171 GST_WARNING_OBJECT (aiff, "Failed to find COMM chunk");
1172 goto no_header;
1173 }
1174 if (!gotdata) {
1175 GST_WARNING_OBJECT (aiff, "Failed to find SSND chunk");
|