1+ #include <assert.h>
12#include <stdio.h>
23#include <time.h>
34#include <stdlib.h>
@@ -30,7 +31,6 @@ typedef struct
3031} GF_HEVCConfig ;
3132typedef void GF_ISOFile ;
3233typedef void GF_GenericSampleDescription ;
33- #include <assert.h>
3434#define GF_4CC (a , b , c , d ) ((((u32)(a)) << 24) | (((u32)(b)) << 16) | (((u32)(c)) << 8) | ((u32)(d)))
3535#include <libavformat/avformat.h>
3636#include <libavcodec/avcodec.h>
@@ -1015,6 +1015,7 @@ static void ffmpeg_stream_to_type_subtype(AVStream *stream, uint32_t *type, uint
10151015 * type = CCX_MEDIA_CLOSED_CAPTION ;
10161016 * subtype = CCX_SUBTYPE_C608 ;
10171017 }
1018+
10181019 else if (par -> codec_id == AV_CODEC_ID_DVD_SUBTITLE )
10191020 {
10201021 * type = CCX_MEDIA_SUBPIC ;
@@ -1089,37 +1090,25 @@ static void sample_free(CCX_ISOSample **s)
10891090 * s = NULL ;
10901091}
10911092
1092- static PacketStore * * collect_packets (AVFormatContext * fmt_ctx )
1093+ static PacketStore * collect_packets_for_stream (AVFormatContext * fmt_ctx , int stream_idx )
10931094{
1094- int n = fmt_ctx -> nb_streams ;
1095- PacketStore * * stores = calloc (n , sizeof (PacketStore * ));
1096- if (!stores )
1095+ PacketStore * ps = packet_store_new ();
1096+ if (!ps )
10971097 return NULL ;
1098- for (int i = 0 ; i < n ; i ++ )
1099- stores [i ] = packet_store_new ();
1098+ av_seek_frame (fmt_ctx , stream_idx , 0 , AVSEEK_FLAG_BACKWARD );
11001099 AVPacket * pkt = av_packet_alloc ();
11011100 while (av_read_frame (fmt_ctx , pkt ) >= 0 )
11021101 {
1103- int idx = pkt -> stream_index ;
1104- if (idx >= 0 && idx < n )
1102+ if (pkt -> stream_index == stream_idx )
11051103 {
11061104 AVPacket * copy = av_packet_alloc ();
11071105 av_packet_ref (copy , pkt );
1108- packet_store_push (stores [ idx ] , copy );
1106+ packet_store_push (ps , copy );
11091107 }
11101108 av_packet_unref (pkt );
11111109 }
11121110 av_packet_free (& pkt );
1113- return stores ;
1114- }
1115-
1116- static void free_stores (PacketStore * * stores , int n )
1117- {
1118- if (!stores )
1119- return ;
1120- for (int i = 0 ; i < n ; i ++ )
1121- packet_store_free (stores [i ]);
1122- free (stores );
1111+ return ps ;
11231112}
11241113
11251114static int do_avc_track (struct lib_ccx_ctx * ctx , AVStream * st , PacketStore * ps , struct cc_subtitle * sub )
@@ -1177,11 +1166,11 @@ static int do_avc_track(struct lib_ccx_ctx *ctx, AVStream *st, PacketStore *ps,
11771166 CCX_ISOSample * s = sample_from_packet (ps -> pkts [i ]);
11781167 if (!s )
11791168 continue ;
1180- status = process_avc_sample (ctx , ts , (GF_AVCConfig * )& cfg , (GF_ISOSample * )s , sub );
1169+ status = process_avc_sample (ctx , ts , (GF_AVCConfig * )( void * ) & cfg , (GF_ISOSample * )( void * )s , sub );
11811170 sample_free (& s );
11821171 if (status != 0 )
11831172 break ;
1184- int prog = (int )((i * 100 ) / ps -> count );
1173+ int prog = (int )((( int64_t ) i * 100 ) / ps -> count );
11851174 if (ctx -> last_reported_progress != prog )
11861175 {
11871176 int cs = (int )(get_fts (dec -> timing , dec -> current_field ) / 1000 );
@@ -1240,11 +1229,11 @@ static int do_hevc_track(struct lib_ccx_ctx *ctx, AVStream *st, PacketStore *ps,
12401229 CCX_ISOSample * s = sample_from_packet (ps -> pkts [i ]);
12411230 if (!s )
12421231 continue ;
1243- status = process_hevc_sample (ctx , ts , (GF_HEVCConfig * )& cfg , (GF_ISOSample * )s , sub );
1232+ status = process_hevc_sample (ctx , ts , (GF_HEVCConfig * )( void * ) & cfg , (GF_ISOSample * )( void * )s , sub );
12441233 sample_free (& s );
12451234 if (status != 0 )
12461235 break ;
1247- int prog = (int )((i * 100 ) / ps -> count );
1236+ int prog = (int )((( int64_t ) i * 100 ) / ps -> count );
12481237 if (ctx -> last_reported_progress != prog )
12491238 {
12501239 int cs = (int )(get_fts (dec -> timing , dec -> current_field ) / 1000 );
@@ -1275,7 +1264,7 @@ static int do_xdvb_track(struct lib_ccx_ctx *ctx, AVStream *st, PacketStore *ps,
12751264 set_fts (dec -> timing );
12761265 process_m2v (enc , dec , (unsigned char * )s -> data , s -> dataLength , sub );
12771266 sample_free (& s );
1278- int prog = (int )((i * 100 ) / ps -> count );
1267+ int prog = (int )((( int64_t ) i * 100 ) / ps -> count );
12791268 if (ctx -> last_reported_progress != prog )
12801269 {
12811270 int cs = (int )(get_fts (dec -> timing , dec -> current_field ) / 1000 );
@@ -1354,7 +1343,7 @@ static int do_vobsub_track(struct lib_ccx_ctx *ctx, AVStream *st, PacketStore *p
13541343 free (vs .data );
13551344 }
13561345 }
1357- int prog = (int )((i * 100 ) / ps -> count );
1346+ int prog = (int )((( int64_t ) i * 100 ) / ps -> count );
13581347 if (ctx -> last_reported_progress != prog )
13591348 {
13601349 int cs = (int )(get_fts (dec -> timing , dec -> current_field ) / 1000 );
@@ -1419,7 +1408,7 @@ static int do_cc_track(struct lib_ccx_ctx *ctx, AVStream *st, PacketStore *ps, u
14191408 atomStart += al ;
14201409 }
14211410 sample_free (& sample );
1422- int prog = (int )((k * 100 ) / ps -> count );
1411+ int prog = (int )((( int64_t ) k * 100 ) / ps -> count );
14231412 if (ctx -> last_reported_progress != prog )
14241413 {
14251414 int cs = (int )(get_fts (dec -> timing , dec -> current_field ) / 1000 );
@@ -1491,29 +1480,32 @@ int processmp4_ffmpeg(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *f
14911480 vob_c ++ ;
14921481 }
14931482 mprint ("MP4: found %d tracks: %d avc, %d hevc, %d cc, %d vobsub\n" , tc , avc_c , hevc_c , cc_c , vob_c );
1494- PacketStore * * stores = collect_packets (fmt );
1495- if (!stores )
1496- {
1497- avformat_close_input (& fmt );
1498- freep (& dec -> xds_ctx );
1499- return -2 ;
1500- }
15011483 for (int i = 0 ; i < tc ; i ++ )
15021484 {
15031485 AVStream * st = fmt -> streams [i ];
15041486 uint32_t type , subtype ;
15051487 ffmpeg_stream_to_type_subtype (st , & type , & subtype );
15061488 uint64_t tt = CCX_MEDIA_TYPE (type , subtype );
1489+ /* Skip streams we don't handle */
1490+ if (type == 0 )
1491+ continue ;
1492+ PacketStore * ps = collect_packets_for_stream (fmt , i );
1493+ if (!ps )
1494+ continue ;
15071495 switch (tt )
15081496 {
15091497 case CCX_MEDIA_TYPE (CCX_MEDIA_VISUAL , CCX_SUBTYPE_XDVB ):
15101498 if (cc_c && !cfg -> mp4vidtrack )
1499+ {
1500+ packet_store_free (ps );
15111501 continue ;
1502+ }
15121503 if (avc_c > 1 )
15131504 switch_output_file (ctx , enc , i );
1514- if (do_xdvb_track (ctx , st , stores [ i ] , & dec_sub ) != 0 )
1505+ if (do_xdvb_track (ctx , st , ps , & dec_sub ) != 0 )
15151506 {
15161507 mprint ("Error xdvb\n" );
1508+ packet_store_free (ps );
15171509 goto cleanup ;
15181510 }
15191511 if (dec_sub .got_output )
@@ -1525,12 +1517,16 @@ int processmp4_ffmpeg(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *f
15251517 break ;
15261518 case CCX_MEDIA_TYPE (CCX_MEDIA_VISUAL , CCX_SUBTYPE_AVC_H264 ):
15271519 if (cc_c && !cfg -> mp4vidtrack )
1520+ {
1521+ packet_store_free (ps );
15281522 continue ;
1523+ }
15291524 if (avc_c > 1 )
15301525 switch_output_file (ctx , enc , i );
1531- if (do_avc_track (ctx , st , stores [ i ] , & dec_sub ) != 0 )
1526+ if (do_avc_track (ctx , st , ps , & dec_sub ) != 0 )
15321527 {
15331528 mprint ("Error avc\n" );
1529+ packet_store_free (ps );
15341530 goto cleanup ;
15351531 }
15361532 if (dec_sub .got_output )
@@ -1543,13 +1539,17 @@ int processmp4_ffmpeg(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *f
15431539 case CCX_MEDIA_TYPE (CCX_MEDIA_VISUAL , CCX_SUBTYPE_HEV1 ):
15441540 case CCX_MEDIA_TYPE (CCX_MEDIA_VISUAL , CCX_SUBTYPE_HVC1 ):
15451541 if (cc_c && !cfg -> mp4vidtrack )
1542+ {
1543+ packet_store_free (ps );
15461544 continue ;
1545+ }
15471546 if (hevc_c > 1 )
15481547 switch_output_file (ctx , enc , i );
15491548 dec -> avc_ctx -> is_hevc = 1 ;
1550- if (do_hevc_track (ctx , st , stores [ i ] , & dec_sub ) != 0 )
1549+ if (do_hevc_track (ctx , st , ps , & dec_sub ) != 0 )
15511550 {
15521551 mprint ("Error hevc\n" );
1552+ packet_store_free (ps );
15531553 goto cleanup ;
15541554 }
15551555 if (dec_sub .got_output )
@@ -1562,9 +1562,10 @@ int processmp4_ffmpeg(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *f
15621562 case CCX_MEDIA_TYPE (CCX_MEDIA_SUBPIC , CCX_SUBTYPE_MPEG4 ):
15631563 if (vob_c > 1 )
15641564 switch_output_file (ctx , enc , i );
1565- if (do_vobsub_track (ctx , st , stores [ i ] , & dec_sub ) != 0 )
1565+ if (do_vobsub_track (ctx , st , ps , & dec_sub ) != 0 )
15661566 {
15671567 mprint ("Error vobsub\n" );
1568+ packet_store_free (ps );
15681569 goto cleanup ;
15691570 }
15701571 if (dec_sub .got_output )
@@ -1574,15 +1575,18 @@ int processmp4_ffmpeg(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *f
15741575 if (type != CCX_MEDIA_CLOSED_CAPTION && type != CCX_MEDIA_SUBT && type != CCX_MEDIA_TEXT )
15751576 break ;
15761577 if (avc_c && cfg -> mp4vidtrack )
1578+ {
1579+ packet_store_free (ps );
15771580 continue ;
1581+ }
15781582 if (cc_c > 1 )
15791583 switch_output_file (ctx , enc , i );
1580- do_cc_track (ctx , st , stores [ i ] , type , subtype , & dec_sub , & mp4_ret );
1584+ do_cc_track (ctx , st , ps , type , subtype , & dec_sub , & mp4_ret );
15811585 break ;
15821586 }
1587+ packet_store_free (ps );
15831588 }
15841589cleanup :
1585- free_stores (stores , tc );
15861590 avformat_close_input (& fmt );
15871591 freep (& dec -> xds_ctx );
15881592 mprint ("\nDone processing '%s'\n" , file );
@@ -1620,7 +1624,12 @@ int dumpchapters_ffmpeg(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char
16201624 mprint ("failed\n" );
16211625 return 5 ;
16221626 }
1623- avformat_find_stream_info (fmt , NULL );
1627+ if (avformat_find_stream_info (fmt , NULL ) < 0 )
1628+ {
1629+ mprint ("failed to find stream info\n" );
1630+ avformat_close_input (& fmt );
1631+ return 5 ;
1632+ }
16241633 mprint ("ok\n" );
16251634 int count = (int )fmt -> nb_chapters ;
16261635 if (count == 0 )
@@ -1689,18 +1698,6 @@ int processmp4(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *file)
16891698 gf_log_set_tool_level (GF_LOG_CONTAINER , GF_LOG_DEBUG );
16901699#endif
16911700
1692- #ifdef ENABLE_FFMPEG_MP4
1693- AVFormatContext * fmt_ctx = NULL ;
1694- if (avformat_open_input (& fmt_ctx , file , NULL , NULL ) < 0 )
1695- {
1696- mprint ("Failed to open input file (avformat_open_input() returned error)\n" );
1697- free (dec_ctx -> xds_ctx );
1698- return -2 ;
1699- }
1700- avformat_find_stream_info (fmt_ctx , NULL );
1701- mprint ("ok\n" );
1702- track_count = fmt_ctx -> nb_streams ;
1703- #else
17041701 if ((f = gf_isom_open (file , GF_ISOM_OPEN_READ , NULL )) == NULL )
17051702 {
17061703 mprint ("Failed to open input file (gf_isom_open() returned error)\n" );
@@ -1709,7 +1706,6 @@ int processmp4(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *file)
17091706 }
17101707 mprint ("ok\n" );
17111708 track_count = gf_isom_get_track_count (f );
1712- #endif
17131709
17141710 avc_track_count = 0 ;
17151711 hevc_track_count = 0 ;
0 commit comments