@@ -54,6 +54,9 @@ GCC_DIAG_OFF(deprecated-declarations)
54
54
#include <libswresample/swresample.h>
55
55
#endif
56
56
57
+ #include <switch_packetizer.h>
58
+ #define SLICE_SIZE (SWITCH_DEFAULT_VIDEO_SIZE + 100)
59
+
57
60
GCC_DIAG_ON (deprecated - declarations )
58
61
#define SCALE_FLAGS SWS_BICUBIC
59
62
#define DFT_RECORD_OFFSET 0
@@ -116,8 +119,6 @@ typedef struct record_helper_s {
116
119
uint64_t last_ts ;
117
120
} record_helper_t ;
118
121
119
-
120
-
121
122
/* file interface */
122
123
123
124
struct av_file_context {
@@ -161,6 +162,11 @@ struct av_file_context {
161
162
162
163
switch_time_t last_vid_write ;
163
164
int audio_timer ;
165
+
166
+ switch_bool_t no_video_decode ;
167
+ switch_queue_t * video_pkt_queue ;
168
+ switch_packetizer_t * packetizer ;
169
+ AVPacket * last_read_pkt ;
164
170
};
165
171
166
172
typedef struct av_file_context av_file_context_t ;
@@ -772,6 +778,15 @@ static int flush_video_queue(switch_queue_t *q, int min)
772
778
return switch_queue_size (q );
773
779
}
774
780
781
+ static void flush_video_pkt_queue (switch_queue_t * q )
782
+ {
783
+ AVPacket * pkt ;
784
+
785
+ while (switch_queue_trypop (q , (void * * )& pkt ) == SWITCH_STATUS_SUCCESS ) {
786
+ av_packet_unref (pkt );
787
+ }
788
+ }
789
+
775
790
static void * SWITCH_THREAD_FUNC video_thread_run (switch_thread_t * thread , void * obj )
776
791
{
777
792
av_file_context_t * context = (av_file_context_t * ) obj ;
@@ -1387,6 +1402,34 @@ GCC_DIAG_ON(deprecated-declarations)
1387
1402
if (context -> has_video && pkt .stream_index == context -> video_st .st -> index ) {
1388
1403
AVFrame * vframe ;
1389
1404
switch_image_t * img ;
1405
+
1406
+ if (context -> no_video_decode ) {
1407
+ if (eof ) {
1408
+ break ;
1409
+ } else {
1410
+ switch_status_t status ;
1411
+ AVPacket * new_pkt = malloc (sizeof (AVPacket ));
1412
+
1413
+ if (0 ) { // debug
1414
+ uint8_t * p = pkt .data ;
1415
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , "size = %u %x %x %x %x %x %x\n" , pkt .size , * p , * (p + 1 ), * (p + 2 ), * (p + 3 ), * (p + 4 ), * (p + 5 ));
1416
+ }
1417
+
1418
+ av_init_packet (new_pkt );
1419
+ av_packet_ref (new_pkt , & pkt );
1420
+ status = switch_queue_push (context -> video_pkt_queue , new_pkt );
1421
+ // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %4u flag=%x pts=%" SWITCH_INT64_T_FMT " dts=%" SWITCH_INT64_T_FMT "\n", pkt.size, pkt.flags, pkt.pts, pkt.dts);
1422
+
1423
+ context -> vid_ready = 1 ;
1424
+ if (status != SWITCH_STATUS_SUCCESS ) {
1425
+ av_packet_unref (new_pkt );
1426
+ free (new_pkt );
1427
+ }
1428
+ av_packet_unref (& pkt );
1429
+ continue ;
1430
+ }
1431
+ }
1432
+
1390
1433
if (!sync ) {
1391
1434
switch_buffer_zero (context -> audio_buffer );
1392
1435
sync = 1 ;
@@ -1680,6 +1723,11 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa
1680
1723
1681
1724
if (context -> has_video ) {
1682
1725
switch_queue_create (& context -> eh .video_queue , context -> read_fps , handle -> memory_pool );
1726
+ context -> no_video_decode = handle -> params && switch_true (switch_event_get_header (handle -> params , "no_video_decode" ));
1727
+ if (context -> no_video_decode ) {
1728
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , "Opening video in no decode mode\n" );
1729
+ switch_queue_create (& context -> video_pkt_queue , 120 * 5 , handle -> memory_pool );
1730
+ }
1683
1731
switch_mutex_init (& context -> eh .mutex , SWITCH_MUTEX_NESTED , handle -> memory_pool );
1684
1732
switch_core_timer_init (& context -> video_timer , "soft" , (int )(1000.0f / context -> read_fps ), 1 , context -> pool );
1685
1733
}
@@ -2177,6 +2225,15 @@ static switch_status_t av_file_close(switch_file_handle_t *handle)
2177
2225
context -> file_read_thread_running = 0 ;
2178
2226
}
2179
2227
2228
+ if (context -> video_pkt_queue ) {
2229
+ flush_video_pkt_queue (context -> video_pkt_queue );
2230
+ switch_queue_term (context -> video_pkt_queue );
2231
+ }
2232
+
2233
+ if (context -> packetizer ) {
2234
+ switch_packetizer_close (& context -> packetizer );
2235
+ }
2236
+
2180
2237
if (context -> file_read_thread ) {
2181
2238
switch_thread_join (& status , context -> file_read_thread );
2182
2239
context -> file_read_thread = NULL ;
@@ -2249,6 +2306,7 @@ static switch_status_t av_file_read(switch_file_handle_t *handle, void *data, si
2249
2306
}
2250
2307
2251
2308
switch_mutex_lock (context -> mutex );
2309
+
2252
2310
while (!context -> file_read_thread_started ) {
2253
2311
switch_thread_cond_wait (context -> cond , context -> mutex );
2254
2312
}
@@ -2334,6 +2392,82 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f
2334
2392
}
2335
2393
#else
2336
2394
2395
+ static switch_status_t no_video_decode_packets (switch_file_handle_t * handle , switch_frame_t * frame , switch_video_read_flag_t flags )
2396
+ {
2397
+ av_file_context_t * context = (av_file_context_t * )handle -> private_info ;
2398
+ MediaStream * mst = & context -> video_st ;
2399
+ AVStream * st = mst -> st ;
2400
+ // AVCodecContext *ctx = st->codec;
2401
+ // int ticks = 0;
2402
+ // int64_t max_delta = 1 * AV_TIME_BASE; // 1 second
2403
+ switch_status_t status = SWITCH_STATUS_SUCCESS ;
2404
+ AVPacket * pkt ;
2405
+ int64_t pts ;
2406
+
2407
+
2408
+ if (!context -> packetizer ) {
2409
+ // uint8_t *p = st->codecpar->extradata;
2410
+ // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %u %x %x %x %x %x %x\n", st->codecpar->extradata_size, *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5));
2411
+
2412
+ context -> packetizer = switch_packetizer_create (SPT_H264_SIZED_BITSTREAM , SLICE_SIZE );
2413
+ if (!context -> packetizer ) return SWITCH_STATUS_FALSE ;
2414
+
2415
+ switch_packetizer_feed_extradata (context -> packetizer , st -> codecpar -> extradata , st -> codecpar -> extradata_size );
2416
+ }
2417
+
2418
+ if (context -> last_read_pkt ) {
2419
+ status = switch_packetizer_read (context -> packetizer , frame );
2420
+ if (status == SWITCH_STATUS_SUCCESS ) {
2421
+ av_packet_unref (context -> last_read_pkt );
2422
+ free (context -> last_read_pkt );
2423
+ context -> last_read_pkt = NULL ;
2424
+ }
2425
+ return status ;
2426
+ }
2427
+
2428
+ status = switch_queue_trypop (context -> video_pkt_queue , (void * * )& pkt );
2429
+
2430
+ if (status != SWITCH_STATUS_SUCCESS || !pkt ) {
2431
+ switch_cond_next ();
2432
+ return SWITCH_STATUS_BREAK ;
2433
+ }
2434
+
2435
+ context -> last_read_pkt = pkt ;
2436
+ status = switch_packetizer_feed (context -> packetizer , pkt -> data , pkt -> size );
2437
+ status = switch_packetizer_read (context -> packetizer , frame );
2438
+ pts = av_rescale_q (pkt -> pts , st -> time_base , AV_TIME_BASE_Q );
2439
+ frame -> timestamp = pts * 9 / 100 ; // scale to sample 900000
2440
+ // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "pts=%" SWITCH_INT64_T_FMT " status = %d\n", pts, status);
2441
+
2442
+ if (status == SWITCH_STATUS_SUCCESS ) {
2443
+ av_packet_unref (context -> last_read_pkt );
2444
+ free (context -> last_read_pkt );
2445
+ context -> last_read_pkt = NULL ;
2446
+ }
2447
+
2448
+
2449
+ if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_MORE_DATA ) {
2450
+ if (!context -> video_start_time ) {
2451
+ context -> video_start_time = switch_time_now () - pts ;
2452
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , "set start time: %" SWITCH_INT64_T_FMT " now: %" SWITCH_INT64_T_FMT " pts: %" SWITCH_INT64_T_FMT "\n" , context -> video_start_time , switch_time_now (), pts );
2453
+ } else if (flags & SVR_BLOCK ) {
2454
+ int64_t sleep = pts - (switch_time_now () - context -> video_start_time );
2455
+ if (sleep > 0 ) {
2456
+ // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "zzZ... %" SWITCH_INT64_T_FMT "\n", sleep);
2457
+ if (sleep > 1000000 ) {
2458
+ sleep = 1000000 ;
2459
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , "but zzZ... %" SWITCH_INT64_T_FMT " at most\n" , sleep );
2460
+ }
2461
+ switch_yield (sleep );
2462
+ } else {
2463
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , "video is late %" SWITCH_INT64_T_FMT "\n" , sleep );
2464
+ }
2465
+ }
2466
+ }
2467
+
2468
+ return status ;
2469
+ }
2470
+
2337
2471
static switch_status_t av_file_read_video (switch_file_handle_t * handle , switch_frame_t * frame , switch_video_read_flag_t flags )
2338
2472
{
2339
2473
av_file_context_t * context = (av_file_context_t * )handle -> private_info ;
@@ -2353,6 +2487,13 @@ static switch_status_t av_file_read_video(switch_file_handle_t *handle, switch_f
2353
2487
return SWITCH_STATUS_BREAK ;
2354
2488
}
2355
2489
2490
+ if (context -> no_video_decode ) {
2491
+ switch_set_flag (frame , SFF_ENCODED );
2492
+ status = no_video_decode_packets (handle , frame , flags );
2493
+ // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "return len=%4u nalu=%02x m=%d ts=%u\n", frame->datalen, *(uint8_t *)frame->data, frame->m, frame->timestamp);
2494
+ return status ;
2495
+ }
2496
+
2356
2497
if (handle -> mm .fps > 0 && handle -> mm .fps < smaller_ts ) {
2357
2498
smaller_ts = handle -> mm .fps ;
2358
2499
}
0 commit comments