@@ -719,6 +719,9 @@ void dinit_encoder(struct encoder_ctx **arg, LLONG current_fts)
719719 write_subtitle_file_footer (ctx , ctx -> out + i );
720720 }
721721
722+ // Clean up teletext multi-page output files (issue #665)
723+ dinit_teletext_outputs (ctx );
724+
722725 free_encoder_context (ctx -> prev );
723726 dinit_output_ctx (ctx );
724727 freep (& ctx -> subline );
@@ -838,6 +841,15 @@ struct encoder_ctx *init_encoder(struct encoder_cfg *opt)
838841 ctx -> segment_last_key_frame = 0 ;
839842 ctx -> nospupngocr = opt -> nospupngocr ;
840843
844+ // Initialize teletext multi-page output arrays (issue #665)
845+ ctx -> tlt_out_count = 0 ;
846+ for (int i = 0 ; i < MAX_TLT_PAGES_EXTRACT ; i ++ )
847+ {
848+ ctx -> tlt_out [i ] = NULL ;
849+ ctx -> tlt_out_pages [i ] = 0 ;
850+ ctx -> tlt_srt_counter [i ] = 0 ;
851+ }
852+
841853 ctx -> prev = NULL ;
842854 return ctx ;
843855}
@@ -1298,3 +1310,168 @@ void switch_output_file(struct lib_ccx_ctx *ctx, struct encoder_ctx *enc_ctx, in
12981310 enc_ctx -> cea_708_counter = 0 ;
12991311 enc_ctx -> srt_counter = 0 ;
13001312}
1313+
1314+ /**
1315+ * Get or create the output file for a specific teletext page (issue #665)
1316+ * Creates output files on-demand with suffix _pNNN (e.g., output_p891.srt)
1317+ * Returns NULL if we're in stdout mode or if too many pages are being extracted
1318+ */
1319+ struct ccx_s_write * get_teletext_output (struct encoder_ctx * ctx , uint16_t teletext_page )
1320+ {
1321+ // If teletext_page is 0, use the default output
1322+ if (teletext_page == 0 || ctx -> out == NULL )
1323+ return ctx -> out ;
1324+
1325+ // Check if we're sending to stdout - can't do multi-page in that case
1326+ if (ctx -> out [0 ].fh == STDOUT_FILENO )
1327+ return ctx -> out ;
1328+
1329+ // Check if we already have an output file for this page
1330+ for (int i = 0 ; i < ctx -> tlt_out_count ; i ++ )
1331+ {
1332+ if (ctx -> tlt_out_pages [i ] == teletext_page )
1333+ return ctx -> tlt_out [i ];
1334+ }
1335+
1336+ // If we only have one teletext page requested, use the default output
1337+ // (no suffix needed for backward compatibility)
1338+ extern struct ccx_s_teletext_config tlt_config ;
1339+ if (tlt_config .num_user_pages <= 1 && !tlt_config .extract_all_pages )
1340+ return ctx -> out ;
1341+
1342+ // Need to create a new output file for this page
1343+ if (ctx -> tlt_out_count >= MAX_TLT_PAGES_EXTRACT )
1344+ {
1345+ mprint ("Warning: Too many teletext pages to extract (max %d), using default output for page %03d\n" ,
1346+ MAX_TLT_PAGES_EXTRACT , teletext_page );
1347+ return ctx -> out ;
1348+ }
1349+
1350+ // Allocate the new write structure
1351+ struct ccx_s_write * new_out = (struct ccx_s_write * )malloc (sizeof (struct ccx_s_write ));
1352+ if (!new_out )
1353+ {
1354+ mprint ("Error: Memory allocation failed for teletext output\n" );
1355+ return ctx -> out ;
1356+ }
1357+ memset (new_out , 0 , sizeof (struct ccx_s_write ));
1358+
1359+ // Create the filename with page suffix
1360+ const char * ext = get_file_extension (ctx -> write_format );
1361+ char suffix [16 ];
1362+ snprintf (suffix , sizeof (suffix ), "_p%03d" , teletext_page );
1363+
1364+ char * basefilename = NULL ;
1365+ if (ctx -> out [0 ].filename != NULL )
1366+ {
1367+ basefilename = get_basename (ctx -> out [0 ].filename );
1368+ }
1369+ else if (ctx -> first_input_file != NULL )
1370+ {
1371+ basefilename = get_basename (ctx -> first_input_file );
1372+ }
1373+ else
1374+ {
1375+ basefilename = strdup ("untitled" );
1376+ }
1377+
1378+ if (basefilename == NULL )
1379+ {
1380+ free (new_out );
1381+ return ctx -> out ;
1382+ }
1383+
1384+ char * filename = create_outfilename (basefilename , suffix , ext );
1385+ free (basefilename );
1386+
1387+ if (filename == NULL )
1388+ {
1389+ free (new_out );
1390+ return ctx -> out ;
1391+ }
1392+
1393+ // Open the file
1394+ new_out -> filename = filename ;
1395+ new_out -> fh = open (filename , O_RDWR | O_CREAT | O_TRUNC | O_BINARY , S_IREAD | S_IWRITE );
1396+ if (new_out -> fh == -1 )
1397+ {
1398+ mprint ("Error: Failed to open output file %s: %s\n" , filename , strerror (errno ));
1399+ free (filename );
1400+ free (new_out );
1401+ return ctx -> out ;
1402+ }
1403+
1404+ mprint ("Creating teletext output file: %s\n" , filename );
1405+
1406+ // Store in our array
1407+ int idx = ctx -> tlt_out_count ;
1408+ ctx -> tlt_out [idx ] = new_out ;
1409+ ctx -> tlt_out_pages [idx ] = teletext_page ;
1410+ ctx -> tlt_srt_counter [idx ] = 0 ;
1411+ ctx -> tlt_out_count ++ ;
1412+
1413+ // Write the subtitle file header
1414+ write_subtitle_file_header (ctx , new_out );
1415+
1416+ return new_out ;
1417+ }
1418+
1419+ /**
1420+ * Get the SRT counter for a specific teletext page (issue #665)
1421+ * Returns pointer to the counter, or NULL if page not found
1422+ */
1423+ unsigned int * get_teletext_srt_counter (struct encoder_ctx * ctx , uint16_t teletext_page )
1424+ {
1425+ // If teletext_page is 0, use the default counter
1426+ if (teletext_page == 0 )
1427+ return & ctx -> srt_counter ;
1428+
1429+ // Check if we're using multi-page mode
1430+ extern struct ccx_s_teletext_config tlt_config ;
1431+ if (tlt_config .num_user_pages <= 1 && !tlt_config .extract_all_pages )
1432+ return & ctx -> srt_counter ;
1433+
1434+ // Find the counter for this page
1435+ for (int i = 0 ; i < ctx -> tlt_out_count ; i ++ )
1436+ {
1437+ if (ctx -> tlt_out_pages [i ] == teletext_page )
1438+ return & ctx -> tlt_srt_counter [i ];
1439+ }
1440+
1441+ // Not found, use default counter
1442+ return & ctx -> srt_counter ;
1443+ }
1444+
1445+ /**
1446+ * Clean up all teletext output files (issue #665)
1447+ */
1448+ void dinit_teletext_outputs (struct encoder_ctx * ctx )
1449+ {
1450+ if (!ctx )
1451+ return ;
1452+
1453+ for (int i = 0 ; i < ctx -> tlt_out_count ; i ++ )
1454+ {
1455+ if (ctx -> tlt_out [i ] != NULL )
1456+ {
1457+ // Write footer
1458+ write_subtitle_file_footer (ctx , ctx -> tlt_out [i ]);
1459+
1460+ // Close file
1461+ if (ctx -> tlt_out [i ]-> fh != -1 )
1462+ {
1463+ close (ctx -> tlt_out [i ]-> fh );
1464+ }
1465+
1466+ // Free filename
1467+ if (ctx -> tlt_out [i ]-> filename != NULL )
1468+ {
1469+ free (ctx -> tlt_out [i ]-> filename );
1470+ }
1471+
1472+ free (ctx -> tlt_out [i ]);
1473+ ctx -> tlt_out [i ] = NULL ;
1474+ }
1475+ }
1476+ ctx -> tlt_out_count = 0 ;
1477+ }
0 commit comments