Skip to content

Commit 31e3c03

Browse files
author
Farzaneh Soltanzadeh
committed
change logic to use ffmpeg funcs to open raw rtp file
1 parent de0d8ab commit 31e3c03

File tree

2 files changed

+64
-132
lines changed

2 files changed

+64
-132
lines changed

daemon/media_player.c

Lines changed: 63 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,57 +1104,6 @@ static int media_player_find_file_begin(struct media_player *mp) {
11041104
static bool media_player_read_packet(struct media_player *mp) {
11051105
if (!mp->coder.fmtctx)
11061106
return true;
1107-
// Handle raw RTP file playback
1108-
if (mp->coder.audio_raw_rtp_mode) {
1109-
// Check if we have more data
1110-
if (mp->coder.audio_raw_rtp_pos >= mp->coder.audio_raw_rtp_data.len) {
1111-
ilog(LOG_DEBUG, "End of raw RTP file reached");
1112-
return true;
1113-
}
1114-
1115-
// Calculate bytes to read (one frame)
1116-
size_t bytes_to_read = MIN(mp->coder.audio_raw_rtp_frame_size,
1117-
mp->coder.audio_raw_rtp_data.len - mp->coder.audio_raw_rtp_pos);
1118-
// Allocate packet
1119-
mp->coder.pkt = av_packet_alloc();
1120-
if (!mp->coder.pkt) {
1121-
ilog(LOG_ERR, "Failed to allocate packet");
1122-
return true;
1123-
}
1124-
1125-
// Fill packet with raw RTP data
1126-
if (av_new_packet(mp->coder.pkt, bytes_to_read) < 0) {
1127-
ilog(LOG_ERR, "Failed to create packet");
1128-
av_packet_free(&mp->coder.pkt);
1129-
return true;
1130-
}
1131-
if (bytes_to_read > 0) {
1132-
memcpy(mp->coder.pkt->data,
1133-
mp->coder.audio_raw_rtp_data.s + mp->coder.audio_raw_rtp_pos,
1134-
bytes_to_read);
1135-
}
1136-
if (bytes_to_read < mp->coder.audio_raw_rtp_frame_size) {
1137-
// Pad with silence if needed
1138-
memset(mp->coder.pkt->data + bytes_to_read,
1139-
mp->coder.silence_byte,
1140-
mp->coder.audio_raw_rtp_frame_size - bytes_to_read);
1141-
ilog(LOG_DEBUG, "Padding %zu bytes of silence",
1142-
mp->coder.audio_raw_rtp_frame_size - bytes_to_read);
1143-
}
1144-
mp->coder.audio_raw_rtp_pos += bytes_to_read;
1145-
1146-
// Simulate packet timing (20ms per frame)
1147-
mp->coder.pkt->pts = mp->last_frame_ts;
1148-
mp->coder.pkt->duration = 160;
1149-
mp->last_frame_ts += mp->coder.pkt->duration;
1150-
// Process packet
1151-
media_player_coder_add_packet(&mp->coder, media_player_add_packet, mp);
1152-
av_packet_free(&mp->coder.pkt);
1153-
1154-
// Schedule next read in 20ms
1155-
mp->next_run = rtpe_now + 20000;
1156-
return false;
1157-
}
11581107

11591108
int ret = av_read_frame(mp->coder.fmtctx, mp->coder.pkt);
11601109
if (ret < 0) {
@@ -1283,18 +1232,17 @@ static bool media_player_play_start(struct media_player *mp, const rtp_payload_t
12831232
return true;
12841233

12851234
mp->next_run = rtpe_now;
1286-
if (!mp->coder.audio_raw_rtp_mode) {
1287-
// give ourselves a bit of a head start with decoding
1288-
mp->next_run -= 50000;
1289-
1290-
// if start_pos is positive, try to seek to that position
1291-
if (mp->opts.start_pos > 0) {
1292-
ilog(LOG_DEBUG, "Seeking to position %lli", mp->opts.start_pos);
1293-
av_seek_frame(mp->coder.fmtctx, 0, mp->opts.start_pos, 0);
1294-
}
1295-
else // in case this is a repeated start
1296-
av_seek_frame(mp->coder.fmtctx, 0, 0, 0);
1235+
// give ourselves a bit of a head start with decoding
1236+
mp->next_run -= 50000;
1237+
1238+
// if start_pos is positive, try to seek to that position
1239+
if (mp->opts.start_pos > 0) {
1240+
ilog(LOG_DEBUG, "Seeking to position %lli", mp->opts.start_pos);
1241+
av_seek_frame(mp->coder.fmtctx, 0, mp->opts.start_pos, 0);
12971242
}
1243+
else // in case this is a repeated start
1244+
av_seek_frame(mp->coder.fmtctx, 0, 0, 0);
1245+
12981246
media_player_read_packet(mp);
12991247

13001248
return true;
@@ -1527,61 +1475,72 @@ static mp_cached_code __media_player_add_file(struct media_player *mp,
15271475
return MPC_OK;
15281476
}
15291477

1478+
struct rtp_payload_data{
1479+
int pt; // RTP payload type
1480+
const char ffmpeg_codec_name[6]; // Codec name (case-sensitive)
1481+
enum AVMediaType codec_type;// Media type
1482+
enum AVCodecID codec_id; // FFmpeg codec ID
1483+
int sample_rate; // Sample rate
1484+
int channels; // Default channels
1485+
};
1486+
1487+
const struct rtp_payload_data rtp_payload_types[] = {
1488+
{0, "mulaw", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_MULAW, 8000, 1},
1489+
{8, "alaw", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_ALAW, 8000, 1},
1490+
{9, "g722", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_ADPCM_G722, 8000, 1},
1491+
{18, "g729", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_G729, 8000, 1},
1492+
{-1, "", AVMEDIA_TYPE_UNKNOWN, AV_CODEC_ID_NONE, -1, -1}
1493+
};
1494+
1495+
// Helper function to find codec configuration
1496+
static const struct rtp_payload_data *find_rtp_payload_data(const str *codec_str) {
1497+
// Check static payload types
1498+
for (int i = 0; rtp_payload_types[i].pt != -1; i++) {
1499+
if (str_cmp(codec_str, rtp_payload_types[i].ffmpeg_codec_name) == 0) {
1500+
return &rtp_payload_types[i];
1501+
}
1502+
}
1503+
ilog(LOG_ERR, "Unsupported codec: '" STR_FORMAT "'", STR_FMT(codec_str));
1504+
return NULL;
1505+
}
1506+
15301507
static bool __media_player_open_audio_raw_rtp_file(struct media_player *mp, media_player_opts_t opts) {
15311508
// Validate codec
15321509
if (!opts.audio_raw_rtp_codec.len) {
15331510
ilog(LOG_ERR, "Raw RTP playback requires codec specification");
15341511
return false;
15351512
}
1536-
1537-
// Convert file path
1538-
char file_path[PATH_MAX];
1539-
snprintf(file_path, sizeof(file_path), STR_FORMAT, STR_FMT(&opts.audio_raw_rtp_file));
15401513

1541-
// Open file
1542-
FILE *f = fopen(file_path, "rb");
1543-
if (!f) {
1544-
ilog(LOG_ERR, "Failed to open raw RTP file: %s", file_path);
1514+
// Find codec configuration
1515+
const struct rtp_payload_data *payload_data = find_rtp_payload_data(&opts.audio_raw_rtp_codec);
1516+
if (!payload_data || payload_data->codec_id == AV_CODEC_ID_NONE) {
1517+
ilog(LOG_ERR, "Codec '" STR_FORMAT "' is not supported by FFmpeg", STR_FMT(&opts.audio_raw_rtp_codec));
15451518
return false;
15461519
}
1520+
1521+
// Convert file path
1522+
char file_path[PATH_MAX];
1523+
snprintf(file_path, sizeof(file_path), STR_FORMAT, STR_FMT(&opts.audio_raw_rtp_file));
15471524

1548-
// Get file size
1549-
fseek(f, 0, SEEK_END);
1550-
long file_size = ftell(f);
1551-
fseek(f, 0, SEEK_SET);
1552-
// Read entire file into memory
1553-
char *file_data = malloc(file_size);
1554-
if (!file_data || fread(file_data, 1, file_size, f) != file_size) {
1555-
ilog(LOG_ERR, "Failed to read raw RTP file");
1556-
fclose(f);
1557-
free(file_data);
1525+
AVInputFormat *iformat = av_find_input_format(opts.audio_raw_rtp_codec.s);
1526+
if (!iformat) {
1527+
ilog(LOG_ERR, "Failed to find input format:'" STR_FORMAT "'", STR_FMT(&opts.audio_raw_rtp_codec));
15581528
return false;
15591529
}
1560-
fclose(f);
1561-
1562-
// Store in player context
1563-
mp->coder.audio_raw_rtp_data.s = file_data;
1564-
mp->coder.audio_raw_rtp_data.len = file_size;
1565-
mp->coder.audio_raw_rtp_pos = 0;
1566-
// Set codec parameters based on input
1567-
if (opts.audio_raw_rtp_codec.len == 4 && strncasecmp(opts.audio_raw_rtp_codec.s, "PCMU", 4) == 0) {
1568-
mp->coder.audio_raw_rtp_codec = AV_CODEC_ID_PCM_MULAW;
1569-
mp->coder.audio_raw_rtp_frame_size = 160; // 20ms frames
1570-
mp->coder.silence_byte = 0xFF; // μ-law silence
1571-
mp->coder.time_base = (AVRational){1, 8000}; // Default for 8kHz audio
1572-
}
1573-
else if (opts.audio_raw_rtp_codec.len == 4 && strncasecmp(opts.audio_raw_rtp_codec.s, "PCMA", 4) == 0) {
1574-
mp->coder.audio_raw_rtp_codec = AV_CODEC_ID_PCM_ALAW;
1575-
mp->coder.audio_raw_rtp_frame_size = 160; // 20ms frames
1576-
mp->coder.silence_byte = 0x55; // A-law silence
1577-
mp->coder.time_base = (AVRational){1, 8000}; // Default for 8kHz audio
1578-
}
1579-
else {
1580-
ilog(LOG_ERR, "Unsupported raw RTP codec: " STR_FORMAT, STR_FMT(&opts.audio_raw_rtp_codec));
1581-
free(file_data);
1530+
1531+
int ret = avformat_open_input(&mp->coder.fmtctx, file_path, iformat , NULL);
1532+
if (ret < 0) {
1533+
ilog(LOG_ERR, "Raw RTP playback failing in avformat_open_input");
1534+
return false;
1535+
}
1536+
1537+
if (!mp->coder.fmtctx->streams || !mp->coder.fmtctx->streams[0]) {
1538+
ilog(LOG_ERR, "No streams found in input file");
15821539
return false;
15831540
}
1584-
1541+
mp->coder.fmtctx->streams[0]->time_base = (AVRational){1, payload_data->sample_rate > 0 ? payload_data->sample_rate : 8000}; // Default for 8kHz audio;
1542+
mp->coder.fmtctx->streams[0]->codecpar->sample_rate = payload_data->sample_rate;
1543+
15851544
return true;
15861545
}
15871546

@@ -1591,28 +1550,7 @@ static bool media_player_play_audio_raw_rtp_file(struct media_player *mp, media_
15911550
return false;
15921551

15931552
if (!__media_player_open_audio_raw_rtp_file(mp, opts))
1594-
return false;
1595-
1596-
// Set up fake format context
1597-
mp->coder.fmtctx = avformat_alloc_context();
1598-
if (!mp->coder.fmtctx) {
1599-
ilog(LOG_ERR, "Failed to alloc format context");
1600-
return false;
1601-
}
1602-
1603-
// Create a dummy stream
1604-
AVStream *stream = avformat_new_stream(mp->coder.fmtctx, NULL);
1605-
if (!stream) {
1606-
ilog(LOG_ERR, "Failed to create stream");
1607-
return false;
1608-
}
1609-
1610-
// Set codec parameters
1611-
stream->time_base = mp->coder.time_base;
1612-
stream->codecpar->codec_id = mp->coder.audio_raw_rtp_codec;
1613-
stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
1614-
stream->codecpar->channels = 1;
1615-
stream->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
1553+
return false;
16161554

16171555
mp->coder.audio_raw_rtp_mode = true;
16181556
return media_player_play_start(mp, dst_pt, opts.codec_set);

include/media_player.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,7 @@ struct media_player_coder {
6262
str blob;
6363
str read_pos;
6464
struct codec_handler *handler;
65-
unsigned int audio_raw_rtp_mode:1;
66-
str audio_raw_rtp_data;
67-
size_t audio_raw_rtp_pos;
68-
int audio_raw_rtp_frame_size;
69-
unsigned char silence_byte;
70-
enum AVCodecID audio_raw_rtp_codec;
71-
AVRational time_base;
65+
unsigned int audio_raw_rtp_mode;
7266
};
7367

7468
struct media_player {

0 commit comments

Comments
 (0)