[FFmpeg-soc] [soc]: r4440 - in concat/libavformat: m3u.c playlist.c playlist.h
gkovacs
subversion at mplayerhq.hu
Sat Jun 13 02:53:22 CEST 2009
Author: gkovacs
Date: Sat Jun 13 02:53:22 2009
New Revision: 4440
Log:
removed unnecessary code, should work with same-codec different-format combinations as-is, requires an (in-progress) patch to ffmpeg.c and ffplay.c to handle changing streams during decoding
Modified:
concat/libavformat/m3u.c
concat/libavformat/playlist.c
concat/libavformat/playlist.h
Modified: concat/libavformat/m3u.c
==============================================================================
--- concat/libavformat/m3u.c Fri Jun 12 21:24:59 2009 (r4439)
+++ concat/libavformat/m3u.c Sat Jun 13 02:53:22 2009 (r4440)
@@ -1,6 +1,6 @@
/*
* M3U muxer and demuxer
- * Copyright (c) 2001 Geza Kovacs
+ * Copyright (c) 2009 Geza Kovacs
*
* This file is part of FFmpeg.
*
@@ -19,12 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * Based on AU muxer and demuxer in au.c
- */
-
#include "avformat.h"
-#include "raw.h"
#include "riff.h"
#include "playlist.h"
@@ -33,187 +28,167 @@
/* The ffmpeg codecs we support, and the IDs they have in the file */
static const AVCodecTag codec_m3u_tags[] = {
- { CODEC_ID_PCM_MULAW, 1 },
- { CODEC_ID_PCM_S8, 2 },
- { CODEC_ID_PCM_S16BE, 3 },
- { CODEC_ID_PCM_S24BE, 4 },
- { CODEC_ID_PCM_S32BE, 5 },
- { CODEC_ID_PCM_F32BE, 6 },
- { CODEC_ID_PCM_F64BE, 7 },
- { CODEC_ID_PCM_ALAW, 27 },
{ 0, 0 },
};
-
-
-#if CONFIG_PLAYLIST_MUXER
-/* AUDIO_FILE header */
-static int put_m3u_header(ByteIOContext *pb, AVCodecContext *enc)
-{
- if(!enc->codec_tag)
- return -1;
- put_tag(pb, ".snd"); /* magic number */
- put_be32(pb, 24); /* header size */
- put_be32(pb, M3U_UNKNOWN_SIZE); /* data size */
- put_be32(pb, (uint32_t)enc->codec_tag); /* codec ID */
- put_be32(pb, enc->sample_rate);
- put_be32(pb, (uint32_t)enc->channels);
- return 0;
-}
-
-static int m3u_write_header(AVFormatContext *s)
-{
- ByteIOContext *pb = s->pb;
-
- s->priv_data = NULL;
-
- /* format header */
- if (put_m3u_header(pb, s->streams[0]->codec) < 0) {
- return -1;
- }
-
- put_flush_packet(pb);
-
- return 0;
-}
-
-static int m3u_write_packet(AVFormatContext *s, AVPacket *pkt)
-{
- ByteIOContext *pb = s->pb;
- put_buffer(pb, pkt->data, pkt->size);
- return 0;
-}
-
-static int m3u_write_trailer(AVFormatContext *s)
-{
- ByteIOContext *pb = s->pb;
- int64_t file_size;
-
- if (!url_is_streamed(s->pb)) {
-
- /* update file size */
- file_size = url_ftell(pb);
- url_fseek(pb, 8, SEEK_SET);
- put_be32(pb, (uint32_t)(file_size - 24));
- url_fseek(pb, file_size, SEEK_SET);
-
- put_flush_packet(pb);
- }
-
- return 0;
-}
-#endif /* CONFIG_M3U_MUXER */
-
-
-
-static int compare_bufs(unsigned char *buf, unsigned char *rbuf)
-{
- while (*rbuf != 0)
- {
- if (*rbuf != *buf)
- return 0;
- ++buf;
- ++rbuf;
- }
- return 1;
-}
-
static int m3u_probe(AVProbeData *p)
{
- if (p->buf_size >= 7 && p->buf != 0)
- {
+ if (p->buf != 0) {
if (compare_bufs(p->buf, "#EXTM3U"))
return AVPROBE_SCORE_MAX;
else
return 0;
}
- if (check_file_extn(p->filename, "m3u"))
+ if (match_ext(p->filename, "m3u"))
return AVPROBE_SCORE_MAX/2;
else
return 0;
}
-static int m3u_list_files(unsigned char *buffer, int buffer_size, unsigned char **file_list, unsigned int *lfx_ptr)
+static int m3u_list_files(ByteIOContext *s,
+ char ***flist_ptr,
+ unsigned int *lfx_ptr,
+ char *workingdir)
{
- unsigned int i;
- unsigned int lfx = 0;
- unsigned int fx = 0;
- unsigned char hashed_out = 0;
- unsigned char fldata[262144];
- memset(fldata, 0, 262144);
- memset(file_list, 0, 512 * sizeof(unsigned char*));
- for (i = 0; i < 512; ++i)
- {
- file_list[i] = fldata+i*512;
- }
- for (i = 0; i < buffer_size; ++i)
- {
- if (buffer[i] == 0)
+ char **ofl;
+ int i;
+ int bufsize = 16;
+ i = 0;
+ ofl = av_malloc(sizeof(char*) * bufsize);
+ while (1) {
+ char *c = buf_getline(s);
+ if (c == NULL) // EOF
break;
- if (buffer[i] == '#')
- {
- hashed_out = 1;
+ if (*c == 0) // hashed out
continue;
+ ofl[i] = c;
+ if (++i == bufsize) {
+ bufsize += 16;
+ ofl = av_realloc(ofl, sizeof(char*) * bufsize);
}
- if (buffer[i] == '\n')
- {
- hashed_out = 0;
- if (fx != 0)
- {
- fx = 0;
- ++lfx;
- }
- continue;
+ }
+ *flist_ptr = ofl;
+ *lfx_ptr = i;
+ ofl[i] = 0;
+ while (*ofl != 0) { // determine if relative paths
+ FILE *file;
+ char *fullfpath = conc_strings(workingdir, *ofl);
+ file = fopen(fullfpath, "r");
+ if (file) {
+ fclose(file);
+ *ofl = fullfpath;
}
- if (hashed_out)
- continue;
- file_list[lfx][fx] = buffer[i];
- ++fx;
+ ++ofl;
}
- *lfx_ptr = lfx;
return 0;
}
-
-
-/* m3u input */
static int m3u_read_header(AVFormatContext *s,
- AVFormatParameters *ap)
+ AVFormatParameters *ap)
{
- unsigned char *flist[512];
- int flist_len;
- ByteIOContext *pb;
- PlaylistD *playld;
- pb = s->pb;
- m3u_list_files(pb->buffer, pb->buffer_size, flist, &flist_len);
- playld = av_make_playlistd(flist, flist_len);
+ printf("m3u read header called\n");
+ PlaylistD *playld = av_malloc(sizeof(PlaylistD));
+ split_wd_fn(s->filename,
+ &playld->workingdir,
+ &playld->filename);
+ m3u_list_files(s->pb,
+ &(playld->flist),
+ &(playld->pelist_size),
+ playld->workingdir);
+// playld = av_make_playlistd(flist, flist_len);
+ playld->pelist = av_malloc(playld->pelist_size * sizeof(PlayElem*));
+ memset(playld->pelist, 0, playld->pelist_size * sizeof(PlayElem*));
+ playld->pe_curidx = 0;
s->priv_data = playld;
playlist_populate_context(playld, s);
return 0;
}
-#define MAX_SIZE 4096
-
static int m3u_read_packet(AVFormatContext *s,
- AVPacket *pkt)
+ AVPacket *pkt)
{
+ int i;
int ret;
+ int time_offset = 0;
PlaylistD *playld;
AVFormatContext *ic;
playld = s->priv_data;
retr:
ic = playld->pelist[playld->pe_curidx]->ic;
ret = ic->iformat->read_packet(ic, pkt);
+// if (pkt) {
+// pkt->stream_index += get_stream_offset(s);
+// }
if (ret < 0 && playld->pe_curidx < playld->pelist_size - 1)
{
++playld->pe_curidx;
- // TODO clear all existing streams before repopulating
+// pkt->destruct(pkt);
+ pkt = av_malloc(sizeof(AVPacket));
playlist_populate_context(playld, s);
goto retr;
}
return ret;
}
+static int m3u_read_seek(AVFormatContext *s,
+ int stream_index,
+ int64_t pts,
+ int flags)
+{
+ PlaylistD *playld;
+ AVFormatContext *ic;
+ playld = s->priv_data;
+ ic = playld->pelist[playld->pe_curidx]->ic;
+ ic->iformat->read_seek(ic, stream_index, pts, flags);
+}
+
+static int m3u_read_play(AVFormatContext *s)
+{
+ printf("m3u_read_play called\n");
+ PlaylistD *playld;
+ AVFormatContext *ic;
+ playld = s->priv_data;
+ ic = playld->pelist[playld->pe_curidx]->ic;
+ return av_read_play(ic);
+}
+
+static int m3u_read_pause(AVFormatContext *s)
+{
+ printf("m3u_read_pause called\n");
+ PlaylistD *playld;
+ AVFormatContext *ic;
+ playld = s->priv_data;
+ ic = playld->pelist[playld->pe_curidx]->ic;
+ return av_read_pause(ic);
+}
+
+static int m3u_read_close(AVFormatContext *s)
+{
+ printf("m3u_read_close called\n");
+ PlaylistD *playld;
+ AVFormatContext *ic;
+ playld = s->priv_data;
+ ic = playld->pelist[playld->pe_curidx]->ic;
+ if (ic->iformat->read_close)
+ return ic->iformat->read_close(ic);
+ return 0;
+}
+
+static int m3u_read_timestamp(AVFormatContext *s,
+ int stream_index,
+ int64_t *pos,
+ int64_t pos_limit)
+{
+ printf("m3u_read_timestamp called\n");
+ PlaylistD *playld;
+ AVFormatContext *ic;
+ playld = s->priv_data;
+ ic = playld->pelist[playld->pe_curidx]->ic;
+ if (ic->iformat->read_timestamp)
+ return ic->iformat->read_timestamp(ic, stream_index, pos, pos_limit);
+ return 0;
+}
+
#if CONFIG_M3U_DEMUXER
AVInputFormat m3u_demuxer = {
"m3u",
@@ -222,24 +197,17 @@ AVInputFormat m3u_demuxer = {
m3u_probe,
m3u_read_header,
m3u_read_packet,
- NULL,
- pcm_read_seek,
- .codec_tag= (const AVCodecTag* const []){codec_m3u_tags, 0},
+ m3u_read_close, //m3u_read_close
+ m3u_read_seek,
+ m3u_read_timestamp, //m3u_read_timestamp
+ NULL, //flags
+ NULL, //extensions
+ NULL, //value
+ m3u_read_play,
+ m3u_read_pause,
+ (const AVCodecTag* const []){codec_m3u_tags, 0},
+ NULL, //m3u_read_seek2
+ NULL, //metadata_conv
+ NULL, //next
};
#endif
-
-#if CONFIG_M3U_MUXER
-AVOutputFormat m3u_muxer = {
- "m3u",
- NULL_IF_CONFIG_SMALL("M3U format"),
- "audio/x-mpegurl",
- "m3u",
- 0,
- CODEC_ID_PCM_S16BE,
- CODEC_ID_NONE,
- m3u_write_header,
- m3u_write_packet,
- m3u_write_trailer,
- .codec_tag= (const AVCodecTag* const []){codec_m3u_tags, 0},
-};
-#endif //CONFIG_M3U_MUXER
Modified: concat/libavformat/playlist.c
==============================================================================
--- concat/libavformat/playlist.c Fri Jun 12 21:24:59 2009 (r4439)
+++ concat/libavformat/playlist.c Sat Jun 13 02:53:22 2009 (r4440)
@@ -1,6 +1,6 @@
/*
- * M3U muxer and demuxer
- * Copyright (c) 2001 Geza Kovacs
+ * General components used by playlist formats
+ * Copyright (c) 2009 Geza Kovacs
*
* This file is part of FFmpeg.
*
@@ -19,42 +19,29 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * Based on AU muxer and demuxer in au.c
- */
-
#include "avformat.h"
#include "playlist.h"
-
-int av_open_input_playelem(PlayElem *pe)
-{
- return av_open_input_file(&(pe->ic), pe->filename, pe->fmt, pe->buf_size, pe->ap);
-}
-
+#include "internal.h"
+#include <time.h>
// based on decode_thread() in ffplay.c
-int av_alloc_playelem(unsigned char *filename, PlayElem *pe)
+int av_alloc_playelem(unsigned char *filename,
+ PlayElem *pe)
{
-// AVProbeData *pd;
AVFormatContext *ic;
AVFormatParameters *ap;
-// pd = av_malloc(sizeof(AVProbeData));
-// ic = av_malloc(sizeof(AVFormatContext));
+ ic = av_malloc(sizeof(AVFormatContext));
ap = av_malloc(sizeof(AVFormatParameters));
memset(ap, 0, sizeof(AVFormatParameters));
ap->width = 0;
ap->height = 0;
ap->time_base = (AVRational){1, 25};
ap->pix_fmt = 0;
-// pd->filename = filename;
-// pd->buf = NULL;
-// pd->buf_size = 0;
pe->ic = ic;
pe->filename = filename;
pe->fmt = 0;
pe->buf_size = 0;
pe->ap = ap;
-// pe->fmt = pe->ic->iformat;
return 0;
}
@@ -65,39 +52,33 @@ PlayElem* av_make_playelem(unsigned char
err = av_alloc_playelem(filename, pe);
if (err < 0)
print_error("during-av_alloc_playelem", err);
- err = av_open_input_playelem(pe);
+ err = av_open_input_file(&(pe->ic), pe->filename, pe->fmt, pe->buf_size, pe->ap);
if (err < 0)
print_error("during-open_input_playelem", err);
pe->fmt = pe->ic->iformat;
- if (!pe->fmt)
- {
+ if (!pe->fmt) {
fprintf(stderr, "pefmt not set\n");
- fflush(stderr);
}
err = av_find_stream_info(pe->ic);
- if (err < 0)
- {
- fprintf(stderr, "failed codec probe av_find_stream_info");
- fflush(stderr);
+ if (err < 0) {
+ fprintf(stderr, "failed codec probe av_find_stream_info\n");
}
- if(pe->ic->pb)
- {
+ if(pe->ic->pb) {
pe->ic->pb->eof_reached = 0;
}
- else
- {
+ else {
fprintf(stderr, "failed pe ic pb not set");
- fflush(stderr);
}
- if(!pe->fmt)
- {
+ if(!pe->fmt) {
fprintf(stderr, "failed pe ic fmt not set");
- fflush(stderr);
}
+ pe->time_offset = 0;
+ pe->indv_time = clock();
return pe;
}
-PlaylistD* av_make_playlistd(unsigned char **flist, int flist_len)
+PlaylistD* av_make_playlistd(unsigned char **flist,
+ int flist_len)
{
int i;
PlaylistD *playld = av_malloc(sizeof(PlaylistD));
@@ -105,63 +86,170 @@ PlaylistD* av_make_playlistd(unsigned ch
playld->pelist_size = flist_len;
playld->pelist = av_malloc(playld->pelist_size * sizeof(PlayElem*));
memset(playld->pelist, 0, playld->pelist_size * sizeof(PlayElem*));
- for (int i = 0; i < playld->pelist_size; ++i)
- {
- playld->pelist[i] = av_make_playelem(flist[i]);
- }
return playld;
}
-int playlist_populate_context(PlaylistD *playld, AVFormatContext *s)
+char* conc_strings(char *string1, char *string2) {
+ char *str1;
+ char *str2;
+ char *str;
+ str1 = string1;
+ str2 = string2;
+ while (*string1 != 0)
+ ++string1;
+ while (*string2 != 0)
+ ++string2;
+ str = av_malloc((string1-str1)+(string2-str2));
+ string1 = str1;
+ string2 = str2;
+ while (*string1 != 0)
+ str[string1-str1] = *(string1++);
+ str += (string1-str1);
+ while (*string2 != 0)
+ str[string2-str2] = *(string2++);
+ return (str-string1)+str1;
+}
+
+char* buf_getline(ByteIOContext *s)
+{
+ char *q;
+ char *oq;
+ int bufsize = 64;
+ q = av_malloc(bufsize);
+ oq = q;
+ while (1) {
+ int c = url_fgetc(s);
+ if (c == EOF)
+ return NULL;
+ if (c == '\n')
+ break;
+ *q = c;
+ if ((++q)-oq == bufsize) {
+ oq = av_realloc(oq, bufsize+64);
+ q = oq + bufsize;
+ bufsize += 64;
+ }
+ }
+ *q = 0;
+ q = oq;
+ while (*q != 0 && *q != '#') {
+ ++q;
+ }
+ *q = 0;
+ oq = av_realloc(oq, (q-oq)+1);
+ return oq;
+}
+
+void split_wd_fn(char *filepath,
+ char **workingdir,
+ char **filename)
+{
+ char *ofp;
+ char *cofp;
+ char *lslash = filepath;
+ ofp = filepath;
+ cofp = filepath;
+ while (*filepath != 0) {
+ if (*filepath == '/' || *filepath == '\\')
+ lslash = filepath+1;
+ ++filepath;
+ }
+ *workingdir = av_malloc((lslash-ofp)+1);
+ *filename = av_malloc((filepath-lslash)+1);
+ while (cofp < lslash)
+ (*workingdir)[cofp-ofp] = *(cofp++);
+ (*workingdir)[cofp-ofp] = 0;
+ while (cofp < filepath)
+ (*filename)[cofp-lslash] = *(cofp++);
+ (*filename)[cofp-lslash] = 0;
+}
+
+int playlist_populate_context(PlaylistD *playld,
+ AVFormatContext *s)
{
int i;
- AVFormatContext *ic = playld->pelist[playld->pe_curidx]->ic;
- AVFormatParameters *nap = playld->pelist[playld->pe_curidx]->ap;
- ic->iformat->read_header(ic, nap);
+// unsigned int stream_offset;
+ AVFormatContext *ic;
+ AVFormatParameters *nap;
+ printf("playlist_populate_context called\n");
+ playld->pelist[playld->pe_curidx] = av_make_playelem(playld->flist[playld->pe_curidx]);
+ ic = playld->pelist[playld->pe_curidx]->ic;
+ nap = playld->pelist[playld->pe_curidx]->ap;
+ ic->iformat->read_header(ic, 0);
+// stream_offset = get_stream_offset(s);
s->nb_streams = ic->nb_streams;
- for (i = 0; i < ic->nb_streams; ++i)
- {
+// s->nb_streams = ic->nb_streams + stream_offset;
+ for (i = 0; i < ic->nb_streams; ++i) {
s->streams[i] = ic->streams[i];
+// s->streams[i+stream_offset] = ic->streams[i];
}
+ // TODO remove this ugly hack
+ s->av_class = ic->av_class;
+ s->oformat = ic->oformat;
+ s->pb = ic->pb;
+ s->timestamp = ic->timestamp;
+ s->year = ic->year;
+ s->track = ic->track;
+ s->ctx_flags = ic->ctx_flags;
+ s->packet_buffer = ic->packet_buffer;
+ s->start_time = ic->start_time;
+ s->duration = ic->duration;
+ s->file_size = ic->file_size;
+ s->bit_rate = ic->bit_rate;
+ s->cur_st = ic->cur_st;
+ s->cur_ptr_deprecated = ic->cur_ptr_deprecated;
+ s->cur_len_deprecated = ic->cur_len_deprecated;
+ s->cur_pkt_deprecated = ic->cur_pkt_deprecated;
+ s->data_offset = ic->data_offset;
+ s->index_built = ic->index_built;
+ s->mux_rate = ic->mux_rate;
+ s->packet_size = ic->packet_size;
+ s->preload = ic->preload;
+ s->max_delay = ic->max_delay;
+ s->loop_output = ic->loop_output;
+ s->flags = ic->flags;
+ s->loop_input = ic->loop_input;
+ s->probesize = ic->probesize;
+ s->max_analyze_duration = ic->max_analyze_duration;
+ s->key = ic->key;
+ s->keylen = ic->keylen;
+ s->nb_programs = ic->nb_programs;
+ s->programs = ic->programs;
+ s->video_codec_id = ic->video_codec_id;
+ s->audio_codec_id = ic->audio_codec_id;
+ s->subtitle_codec_id = ic->subtitle_codec_id;
+ s->max_index_size = ic->max_index_size;
+ s->max_picture_buffer = ic->max_picture_buffer;
+ s->nb_chapters = ic->nb_chapters;
+ s->chapters = ic->chapters;
+ s->debug = ic->debug;
+ s->raw_packet_buffer = ic->raw_packet_buffer;
+ s->raw_packet_buffer_end = ic->raw_packet_buffer_end;
+ s->packet_buffer_end = ic->packet_buffer_end;
+ s->metadata = ic->metadata;
return 0;
}
-int check_file_extn(char *cch, char *extn)
+int compare_bufs(unsigned char *buf,
+ unsigned char *rbuf)
{
- int pos;
- int extnl;
- pos = -1;
- extnl = 0;
- while (extn[extnl] != 0)
- ++extnl;
- pos = -1;
- if (!cch)
- {
- return 0;
- }
- if (*cch == 0)
- {
- return 0;
- }
- while (*cch != 0)
- {
- if (*cch == '.')
- {
- pos = 0;
- }
- else if (pos >= 0)
- {
- if (*cch == extn[pos])
- ++pos;
- else
- pos = -1;
- if (pos == extnl)
- {
- return 1;
- }
- }
- ++cch;
+ while (*rbuf != 0) {
+ if (*rbuf != *buf)
+ return 0;
+ ++buf;
+ ++rbuf;
}
- return 0;
+ return 1;
+}
+
+unsigned int get_stream_offset(AVFormatContext *s)
+{
+ PlaylistD *playld;
+ int i;
+ unsigned int snum = 0;
+ playld = s->priv_data;
+ for (i = 0; i < playld->pe_curidx; ++i)
+ snum += playld->pelist[i]->ic->nb_streams;
+ return snum;
}
Modified: concat/libavformat/playlist.h
==============================================================================
--- concat/libavformat/playlist.h Fri Jun 12 21:24:59 2009 (r4439)
+++ concat/libavformat/playlist.h Sat Jun 13 02:53:22 2009 (r4440)
@@ -1,6 +1,6 @@
/*
- * M3U muxer and demuxer
- * Copyright (c) 2001 Geza Kovacs
+ * General components used by playlist formats
+ * Copyright (c) 2009 Geza Kovacs
*
* This file is part of FFmpeg.
*
@@ -19,10 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/*
- * Based on AU muxer and demuxer in au.c
- */
-
typedef struct PlayElem {
AVFormatContext *ic;
@@ -30,12 +26,21 @@ typedef struct PlayElem {
AVInputFormat *fmt;
int buf_size;
AVFormatParameters *ap;
+ int64_t time_offset;
+ int64_t indv_time;
} PlayElem;
typedef struct PlaylistD {
+ char **flist;
+// int flist_len;
PlayElem **pelist;
int pelist_size;
int pe_curidx;
+ AVChapter **chlist;
+ int chlist_size;
+ int ch_curidx;
+ char *workingdir;
+ char *filename;
} PlaylistD;
int av_open_input_playelem(PlayElem *pe);
@@ -46,5 +51,14 @@ PlaylistD* av_make_playlistd(unsigned ch
int check_file_extn(char *cch, char *extn);
+int compare_bufs(unsigned char *buf, unsigned char *rbuf);
+
int playlist_populate_context(PlaylistD *playld, AVFormatContext *s);
+char* conc_strings(char *string1, char *string2);
+
+char* buf_getline(ByteIOContext *s);
+
+void split_wd_fn(char *filepath, char **workingdir, char **filename);
+
+unsigned int get_stream_offset(AVFormatContext *s);
More information about the FFmpeg-soc
mailing list