• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Microsoft Smooth-Streaming fragment parsing library
3  *
4  * gstmssfragmentparser.h
5  *
6  * Copyright (C) 2016 Igalia S.L
7  * Copyright (C) 2016 Metrological
8  *   Author: Philippe Normand <philn@igalia.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library (COPYING); if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */
25 
26 #include "gstmssfragmentparser.h"
27 #include <gst/base/gstbytereader.h>
28 #include <string.h>
29 
30 GST_DEBUG_CATEGORY_EXTERN (mssdemux_debug);
31 #define GST_CAT_DEFAULT mssdemux_debug
32 
33 void
gst_mss_fragment_parser_init(GstMssFragmentParser * parser)34 gst_mss_fragment_parser_init (GstMssFragmentParser * parser)
35 {
36   parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_INIT;
37 }
38 
39 void
gst_mss_fragment_parser_clear(GstMssFragmentParser * parser)40 gst_mss_fragment_parser_clear (GstMssFragmentParser * parser)
41 {
42   if (parser->moof)
43     gst_isoff_moof_box_free (parser->moof);
44   parser->moof = NULL;
45   parser->current_fourcc = 0;
46 }
47 
48 gboolean
gst_mss_fragment_parser_add_buffer(GstMssFragmentParser * parser,GstBuffer * buffer)49 gst_mss_fragment_parser_add_buffer (GstMssFragmentParser * parser,
50     GstBuffer * buffer)
51 {
52   GstByteReader reader;
53   GstMapInfo info;
54   guint64 size;
55   guint32 fourcc;
56   guint header_size;
57   gboolean error = FALSE;
58 
59   if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) {
60     return FALSE;
61   }
62 
63   gst_byte_reader_init (&reader, info.data, info.size);
64   GST_TRACE ("Total buffer size: %u", gst_byte_reader_get_size (&reader));
65 
66   do {
67     parser->current_fourcc = 0;
68 
69     if (!gst_isoff_parse_box_header (&reader, &fourcc, NULL, &header_size,
70             &size)) {
71       break;
72     }
73 
74     parser->current_fourcc = fourcc;
75 
76     GST_LOG ("box %" GST_FOURCC_FORMAT " size %" G_GUINT64_FORMAT,
77         GST_FOURCC_ARGS (fourcc), size);
78 
79     parser->current_fourcc = fourcc;
80 
81     if (parser->current_fourcc == GST_ISOFF_FOURCC_MOOF) {
82       GstByteReader sub_reader;
83 
84       g_assert (parser->moof == NULL);
85       gst_byte_reader_get_sub_reader (&reader, &sub_reader, size - header_size);
86       parser->moof = gst_isoff_moof_box_parse (&sub_reader);
87       if (parser->moof == NULL) {
88         GST_ERROR ("Failed to parse moof");
89         error = TRUE;
90       }
91     } else if (parser->current_fourcc == GST_ISOFF_FOURCC_MDAT) {
92       goto beach;
93     } else {
94       gst_byte_reader_skip (&reader, size - header_size);
95     }
96   } while (gst_byte_reader_get_remaining (&reader) > 0);
97 
98 beach:
99 
100   /* Do sanity check */
101   if (parser->current_fourcc != GST_ISOFF_FOURCC_MDAT || !parser->moof ||
102       parser->moof->traf->len == 0)
103     error = TRUE;
104 
105   if (!error) {
106     GstTrafBox *traf = &g_array_index (parser->moof->traf, GstTrafBox, 0);
107     if (!traf->tfxd) {
108       GST_ERROR ("no tfxd box");
109       error = TRUE;
110     } else if (!traf->tfrf) {
111       GST_ERROR ("no tfrf box");
112       error = TRUE;
113     }
114   }
115 
116   if (!error)
117     parser->status = GST_MSS_FRAGMENT_HEADER_PARSER_FINISHED;
118 
119   GST_LOG ("Fragment parsing successful: %s", error ? "no" : "yes");
120   gst_buffer_unmap (buffer, &info);
121   return !error;
122 }
123