| /* |
| * Microsoft Smooth-Streaming fragment parsing library |
| * |
| * gstmssfragmentparser.h |
| * |
| * Copyright (C) 2016 Igalia S.L |
| * Copyright (C) 2016 Metrological |
| * Author: Philippe Normand <philn@igalia.com> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library (COPYING); if not, write to the |
| * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| * Boston, MA 02111-1307, USA. |
| */ |
| |
| #include "gstmssfragmentparser.h" |
| #include <gst/base/gstbytereader.h> |
| #include <string.h> |
| |
| GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug); |
| #define GST_CAT_DEFAULT mssdemux_debug |
| |
| void |
| gst_mss_fragment_parser_init (GstMssFragmentParser * parser) |
| { |
| parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_INIT; |
| } |
| |
| void |
| gst_mss_fragment_parser_clear (GstMssFragmentParser * parser) |
| { |
| if (parser->moof) |
| gst_isoff_moof_box_free (parser->moof); |
| parser->moof = NULL; |
| parser->current_fourcc = 0; |
| } |
| |
| gboolean |
| gst_mss_fragment_parser_add_buffer (GstMssFragmentParser * parser, |
| GstBuffer * buffer) |
| { |
| GstByteReader reader; |
| GstMapInfo info; |
| guint64 size; |
| guint32 fourcc; |
| guint header_size; |
| gboolean error = FALSE; |
| |
| if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { |
| return FALSE; |
| } |
| |
| gst_byte_reader_init (&reader, info.data, info.size); |
| GST_TRACE ("Total buffer size: %u", gst_byte_reader_get_size (&reader)); |
| |
| do { |
| parser->current_fourcc = 0; |
| |
| if (!gst_isoff_parse_box_header (&reader, &fourcc, NULL, &header_size, |
| &size)) { |
| break; |
| } |
| |
| parser->current_fourcc = fourcc; |
| |
| GST_LOG ("box %" GST_FOURCC_FORMAT " size %" G_GUINT64_FORMAT, |
| GST_FOURCC_ARGS (fourcc), size); |
| |
| parser->current_fourcc = fourcc; |
| |
| if (parser->current_fourcc == GST_ISOFF_FOURCC_MOOF) { |
| GstByteReader sub_reader; |
| |
| g_assert (parser->moof == NULL); |
| gst_byte_reader_get_sub_reader (&reader, &sub_reader, size - header_size); |
| parser->moof = gst_isoff_moof_box_parse (&sub_reader); |
| if (parser->moof == NULL) { |
| GST_ERROR ("Failed to parse moof"); |
| error = TRUE; |
| } |
| } else if (parser->current_fourcc == GST_ISOFF_FOURCC_MDAT) { |
| goto beach; |
| } else { |
| gst_byte_reader_skip (&reader, size - header_size); |
| } |
| } while (gst_byte_reader_get_remaining (&reader) > 0); |
| |
| beach: |
| |
| /* Do sanity check */ |
| if (parser->current_fourcc != GST_ISOFF_FOURCC_MDAT || !parser->moof || |
| parser->moof->traf->len == 0) |
| error = TRUE; |
| |
| if (!error) { |
| GstTrafBox *traf = &g_array_index (parser->moof->traf, GstTrafBox, 0); |
| if (!traf->tfxd) { |
| GST_ERROR ("no tfxd box"); |
| error = TRUE; |
| } else if (!traf->tfrf) { |
| GST_ERROR ("no tfrf box"); |
| error = TRUE; |
| } |
| } |
| |
| if (!error) |
| parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_FINISHED; |
| |
| GST_LOG ("Fragment parsing successful: %s", error ? "no" : "yes"); |
| gst_buffer_unmap (buffer, &info); |
| return !error; |
| } |