@@ -36,33 +36,42 @@ typedef struct WebAVStream
3636 std::string codec_name;
3737 std::string codec_string;
3838 std::string profile;
39- std::string pix_fmt;
40- std::string color_primaries;
41- std::string color_transfer;
42- std::string color_space;
43- std::string color_range;
4439 int level;
45- int width;
46- int height;
47- int channels;
48- int sample_rate;
49- std::string sample_fmt;
5040 std::string bit_rate;
5141 int extradata_size;
5242 std::vector<uint8_t > extradata;
5343 val get_extradata () const {
5444 return val (typed_memory_view (extradata.size (), extradata.data ()));
5545 }
56- /* * Other Info */
46+ /* * Video-specific Info */
47+ int width;
48+ int height;
49+ std::string pix_fmt;
50+ std::string color_primaries;
51+ std::string color_transfer;
52+ std::string color_space;
53+ std::string color_range;
5754 std::string r_frame_rate;
5855 std::string avg_frame_rate;
5956 std::string sample_aspect_ratio;
6057 std::string display_aspect_ratio;
58+ double rotation;
59+ /* * Audio-specific Info */
60+ int channels;
61+ int sample_rate;
62+ std::string sample_fmt;
63+ /* * Other Common Info */
6164 double start_time;
6265 double duration;
63- double rotation;
6466 std::string nb_frames;
6567 std::vector<Tag> tags;
68+ val get_tags () const {
69+ val tags = val::object ();
70+ for (const Tag &tag : this ->tags ) {
71+ tags.set (tag.key , tag.value );
72+ }
73+ return tags;
74+ }
6675} WebAVStream;
6776
6877typedef struct WebAVPacket
@@ -124,6 +133,10 @@ std::string gen_rational_str(AVRational rational, char sep)
124133 return oss.str ();
125134}
126135
136+ inline std::string safe_str (const char * str) {
137+ return str ? str : " " ;
138+ }
139+
127140void gen_web_packet (WebAVPacket &web_packet, AVPacket *packet, AVStream *stream)
128141{
129142 double packet_timestamp = packet->pts * av_q2d (stream->time_base );
@@ -147,41 +160,77 @@ void gen_web_stream(WebAVStream &web_stream, AVStream *stream, AVFormatContext *
147160 web_stream.index = stream->index ;
148161 web_stream.id = stream->id ;
149162
150- // codecpar info
163+ // Initialize codec info
151164 AVCodecParameters *par = stream->codecpar ;
152165 web_stream.codec_type = (int )par->codec_type ;
153- web_stream.codec_type_string = av_get_media_type_string (par->codec_type );
154- web_stream.codec_name = avcodec_descriptor_get (par->codec_id )->name ;
166+ web_stream.codec_type_string = safe_str (av_get_media_type_string (par->codec_type ));
167+
168+ const AVCodecDescriptor* desc = avcodec_descriptor_get (par->codec_id );
169+ web_stream.codec_name = safe_str (desc ? desc->name : " " );
170+
171+ // Initialize video-specific values
172+ web_stream.width = 0 ;
173+ web_stream.height = 0 ;
174+ web_stream.color_primaries = " " ;
175+ web_stream.color_transfer = " " ;
176+ web_stream.color_space = " " ;
177+ web_stream.color_range = " " ;
178+ web_stream.pix_fmt = " " ;
179+ web_stream.r_frame_rate = " 0/0" ;
180+ web_stream.avg_frame_rate = " 0/0" ;
181+ web_stream.rotation = 0 ;
182+ web_stream.sample_aspect_ratio = " N/A" ;
183+ web_stream.display_aspect_ratio = " N/A" ;
184+ // Initialize audio-specific values
185+ web_stream.channels = 0 ;
186+ web_stream.sample_rate = 0 ;
187+ web_stream.sample_fmt = " " ;
155188
156189 char codec_string[40 ];
157190
158191 if (par->codec_type == AVMEDIA_TYPE_VIDEO)
159192 {
160- web_stream.color_primaries = av_color_primaries_name (par->color_primaries );
161- web_stream.color_transfer = av_color_transfer_name (par->color_trc );
162- web_stream.color_space = av_color_space_name (par->color_space );
163- web_stream.color_range = av_color_range_name (par->color_range );
193+ // Video-specific properties
194+ web_stream.width = par->width ;
195+ web_stream.height = par->height ;
196+ web_stream.color_primaries = safe_str (av_color_primaries_name (par->color_primaries ));
197+ web_stream.color_transfer = safe_str (av_color_transfer_name (par->color_trc ));
198+ web_stream.color_space = safe_str (av_color_space_name (par->color_space ));
199+ web_stream.color_range = safe_str (av_color_range_name (par->color_range ));
200+ web_stream.pix_fmt = safe_str (av_get_pix_fmt_name ((AVPixelFormat)par->format ));
201+ web_stream.r_frame_rate = gen_rational_str (stream->r_frame_rate , ' /' );
202+ web_stream.avg_frame_rate = gen_rational_str (stream->avg_frame_rate , ' /' );
203+ web_stream.rotation = get_rotation (stream);
204+
205+ AVRational sar = av_guess_sample_aspect_ratio (fmt_ctx, stream, NULL );
206+ if (sar.num ) {
207+ AVRational dar;
208+ av_reduce (&dar.num , &dar.den , par->width * sar.num , par->height * sar.den , 1024 * 1024 );
209+ web_stream.sample_aspect_ratio = gen_rational_str (sar, ' :' );
210+ web_stream.display_aspect_ratio = gen_rational_str (dar, ' :' );
211+ }
212+
164213 set_video_codec_string (codec_string, sizeof (codec_string), par, &stream->avg_frame_rate );
165214 }
166215 else if (par->codec_type == AVMEDIA_TYPE_AUDIO)
167216 {
217+ // Audio-specific properties
218+ web_stream.channels = par->ch_layout .nb_channels ;
219+ web_stream.sample_rate = par->sample_rate ;
220+ web_stream.sample_fmt = safe_str (av_get_sample_fmt_name ((AVSampleFormat)par->format ));
168221 set_audio_codec_string (codec_string, sizeof (codec_string), par);
169222 }
170223 else
171224 {
172225 strcpy (codec_string, " undf" );
173226 }
174227
175- web_stream. codec_string = codec_string;
176- web_stream.profile = avcodec_profile_name (par-> codec_id , par-> profile );
177- web_stream.pix_fmt = av_get_pix_fmt_name ((AVPixelFormat) par->format );
228+ // Common properties for all types
229+ web_stream.codec_string = safe_str (codec_string );
230+ web_stream.profile = safe_str ( avcodec_profile_name ( par->codec_id , par-> profile ) );
178231 web_stream.level = par->level ;
179- web_stream.width = par->width ;
180- web_stream.height = par->height ;
181- web_stream.channels = par->ch_layout .nb_channels ;
182- web_stream.sample_rate = par->sample_rate ;
183- web_stream.sample_fmt = av_get_sample_fmt_name ((AVSampleFormat)par->format );
184232 web_stream.bit_rate = std::to_string (par->bit_rate );
233+
185234 web_stream.extradata_size = par->extradata_size ;
186235 if (par->extradata_size > 0 )
187236 {
@@ -192,10 +241,8 @@ void gen_web_stream(WebAVStream &web_stream, AVStream *stream, AVFormatContext *
192241 web_stream.extradata = std::vector<uint8_t >();
193242 }
194243
195- // other stream info
196244 web_stream.start_time = stream->start_time * av_q2d (stream->time_base );
197245 web_stream.duration = stream->duration > 0 ? stream->duration * av_q2d (stream->time_base ) : fmt_ctx->duration * av_q2d (AV_TIME_BASE_Q); // TODO: some file type can not get stream duration
198- web_stream.rotation = get_rotation (stream);
199246
200247 int64_t nb_frames = stream->nb_frames ;
201248
@@ -205,30 +252,13 @@ void gen_web_stream(WebAVStream &web_stream, AVStream *stream, AVFormatContext *
205252 nb_frames = (fmt_ctx->duration * (double )stream->avg_frame_rate .num ) / ((double )stream->avg_frame_rate .den * AV_TIME_BASE);
206253 }
207254 web_stream.nb_frames = std::to_string (nb_frames);
208- web_stream.r_frame_rate = gen_rational_str (stream->r_frame_rate , ' /' );
209- web_stream.avg_frame_rate = gen_rational_str (stream->avg_frame_rate , ' /' );
210- AVRational sar, dar;
211- sar = av_guess_sample_aspect_ratio (fmt_ctx, stream, NULL );
212-
213- if (sar.num )
214- {
215- av_reduce (&dar.num , &dar.den , par->width * sar.num , par->height * sar.den , 1024 * 1024 );
216- web_stream.sample_aspect_ratio = gen_rational_str (sar, ' :' );
217- web_stream.display_aspect_ratio = gen_rational_str (dar, ' :' );
218- }
219- else
220- {
221- web_stream.sample_aspect_ratio = std::string (" N/A" );
222- web_stream.display_aspect_ratio = std::string (" N/A" );
223- }
224255
225256 AVDictionaryEntry *tag = NULL ;
226-
227257 while ((tag = av_dict_get (stream->metadata , " " , tag, AV_DICT_IGNORE_SUFFIX)))
228258 {
229259 Tag t = {
230- .key = tag->key ,
231- .value = tag->value ,
260+ .key = safe_str ( tag->key ) ,
261+ .value = safe_str ( tag->value )
232262 };
233263 web_stream.tags .push_back (t);
234264 }
@@ -641,7 +671,7 @@ EMSCRIPTEN_BINDINGS(web_demuxer)
641671 .property (" duration" , &WebAVStream::duration)
642672 .property (" rotation" , &WebAVStream::rotation)
643673 .property (" nb_frames" , &WebAVStream::nb_frames)
644- .property (" tags" , &WebAVStream::tags )
674+ .property (" tags" , &WebAVStream::get_tags )
645675 .property (" color_primaries" , &WebAVStream::color_primaries)
646676 .property (" color_transfer" , &WebAVStream::color_transfer)
647677 .property (" color_space" , &WebAVStream::color_space)
0 commit comments