[FFmpeg-devel] [PATCH] options to set stream id (custom TS pid)
Stefano Sabatini
stefano.sabatini-lala
Sun Jun 13 23:52:11 CEST 2010
On date Sunday 2010-06-13 10:12:26 -0400, Mike Scheutzow encoded:
> Baptiste Coudurier wrote:
> >
> >>@@ -419,7 +424,28 @@
> >> goto fail;
> >> st->priv_data = ts_st;
> >> ts_st->service = service;
> >>- ts_st->pid = DEFAULT_START_PID + i;
> >>+ /* MPEG pid values< 16 are reserved. Applications
> >>which set st->id in
> >>+ * this range are assigned a calculated pid. */
> >>+ if ( st->id< 16 ) {
> >
> >Space around parentheses.
> Fixed in v5 patch.
> >
> >
> >Patch ok otherwise.
> >
>
> Suggested commit description for ffmpeg_set_streamid_v3.patch:
> for ffmpeg.c, add command line option -streamid to set the value of
> AVStream.id for output streams.
> Patch by Mike Scheutzow mjs973 optonline net
>
> Suggested commit description for mpegts_custom_pids_v5.patch:
> for mpegts muxer, allow libav application to assign a custom pid
> value to an output stream.
> Patch by Mike Scheutzow mjs973 optonline net
>
> --
> Mike Scheutzow
>
>
> Index: ffmpeg.c
> ===================================================================
> --- ffmpeg.c (revision 23373)
> +++ ffmpeg.c (working copy)
> @@ -121,6 +121,9 @@
> static AVMetaDataMap meta_data_maps[MAX_FILES];
> static int nb_meta_data_maps;
>
> +/* indexed by output file stream index */
> +static int streamid_map[MAX_STREAMS];
> +
> static int frame_width = 0;
> static int frame_height = 0;
> static float frame_aspect_ratio = 0;
> @@ -3326,7 +3329,7 @@
> AVCodecContext *video_enc;
> enum CodecID codec_id;
>
> - st = av_new_stream(oc, oc->nb_streams);
> + st = av_new_stream(oc, streamid_map[oc->nb_streams]);
> if (!st) {
> fprintf(stderr, "Could not alloc stream\n");
> av_exit(1);
> @@ -3463,7 +3466,7 @@
> AVCodecContext *audio_enc;
> enum CodecID codec_id;
>
> - st = av_new_stream(oc, oc->nb_streams);
> + st = av_new_stream(oc, streamid_map[oc->nb_streams]);
> if (!st) {
> fprintf(stderr, "Could not alloc stream\n");
> av_exit(1);
> @@ -3535,7 +3538,7 @@
> AVStream *st;
> AVCodecContext *subtitle_enc;
>
> - st = av_new_stream(oc, oc->nb_streams);
> + st = av_new_stream(oc, streamid_map[oc->nb_streams]);
> if (!st) {
> fprintf(stderr, "Could not alloc stream\n");
> av_exit(1);
> @@ -3603,6 +3606,27 @@
> new_subtitle_stream(oc);
> }
>
> +/* arg format is "output-stream-index:streamid-value". */
> +static void opt_streamid(const char *arg)
void opt_streamid(const char *opt, const char *arg)
then you can use opt in the error messages, rather than hardcode them.
> +{
> + int idx, value;
> + char *p;
> +
> + idx = strtol(arg, &p, 0);
parse_number_or_die()
> + if (*p != ':' || idx < 0 || idx >= MAX_STREAMS) {
> + fprintf(stderr, "Invalid -streamid: '%s'\n", arg);
> + av_exit(1);
> + }
> +
> + p++;
> + value = strtol(p, &p, 0);
> + if (*p || value < 0) {
> + fprintf(stderr, "Invalid -streamid: '%s'\n", arg);
> + av_exit(1);
> + }
ditto
> + streamid_map[idx] = value;
> +}
> +
> static void opt_output_file(const char *filename)
> {
> AVFormatContext *oc;
> @@ -3750,6 +3774,8 @@
> oc->flags |= AVFMT_FLAG_NONBLOCK;
>
> set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM);
> +
> + memset(streamid_map, 0, sizeof(streamid_map));
> }
>
> /* same option as mencoder */
> @@ -4208,6 +4234,7 @@
> { "vlang", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void *)&video_language}, "set the ISO 639 language code (3 letters) of the current video stream" , "code" },
> { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
> { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" },
> + { "streamid", HAS_ARG | OPT_EXPERT, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" },
>
> /* audio options */
> { "ab", OPT_FUNC2 | HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },
> Index: doc/ffmpeg-doc.texi
> ===================================================================
> --- doc/ffmpeg-doc.texi (revision 23373)
> +++ doc/ffmpeg-doc.texi (working copy)
> @@ -783,6 +783,13 @@
> Set the maximum demux-decode delay.
> @item -muxpreload @var{seconds}
> Set the initial demux-decode delay.
> + at item -streamid @var{output-stream-index}:@var{new-value}
> +Assign a new value to a stream's stream-id field in the next output file. All stream-id fields are reset to default for each output file.
> +
> +For example, to set the stream 0 PID to 33 and the stream 1 PID to 36 for an output mpegts file:
Break long lines
> + at example
> +ffmpeg -i infile -streamid 0:33 -streamid 1:36 out.ts
> + at end example
> @end table
>
> @section Preset files
> Index: libavformat/mpegtsenc.c
> ===================================================================
> --- libavformat/mpegtsenc.c (revision 23373)
> +++ libavformat/mpegtsenc.c (working copy)
> @@ -387,8 +387,9 @@
> MpegTSService *service;
> AVStream *st, *pcr_st = NULL;
> AVMetadataTag *title;
> - int i;
> + int i, j;
> const char *service_name;
> + int *pids;
>
> ts->tsid = DEFAULT_TSID;
> ts->onid = DEFAULT_ONID;
> @@ -411,6 +412,10 @@
> ts->sdt.write_packet = section_write_packet;
> ts->sdt.opaque = s;
>
> + pids = av_malloc(s->nb_streams);
> + if (!pids)
> + return AVERROR(ENOMEM);
> +
> /* assign pids to each stream */
> for(i = 0;i < s->nb_streams; i++) {
> st = s->streams[i];
> @@ -419,7 +424,28 @@
> goto fail;
> st->priv_data = ts_st;
> ts_st->service = service;
> - ts_st->pid = DEFAULT_START_PID + i;
> + /* MPEG pid values < 16 are reserved. Applications which set st->id in
> + * this range are assigned a calculated pid. */
> + if (st->id < 16) {
> + ts_st->pid = DEFAULT_START_PID + i;
> + } else if (st->id < 0x1FFF) {
> + ts_st->pid = st->id;
> + } else {
> + av_log(s, AV_LOG_ERROR, "error, stream id must be 16 to 8190\n");
"Invalid stream id %d, must be in the range..."
> + goto fail;
> + }
> + if (ts_st->pid == service->pmt.pid) {
> + av_log(s, AV_LOG_ERROR, "error, stream id conflicts with PMT (%d)\n",
"Stream id %d conflicts ..."
> + service->pmt.pid);
> + goto fail;
> + }
> + for (j = 0; j < i; j++)
> + if (pids[j] == ts_st->pid) {
> + av_log(s, AV_LOG_ERROR, "error, stream %d id conflicts with "
> + "stream %d (%d)\n", i, j, st->id);
Confusing message.
All these "error, " are ugly, just remove them.
> + goto fail;
> + }
> + pids[i] = ts_st->pid;
> ts_st->payload_pts = AV_NOPTS_VALUE;
> ts_st->payload_dts = AV_NOPTS_VALUE;
> ts_st->first_pts_check = 1;
> @@ -441,6 +467,8 @@
> }
> }
>
> + av_free(pids);
> +
> /* if no video stream, use the first stream as PCR */
> if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
> pcr_st = s->streams[0];
> @@ -496,6 +524,7 @@
> return 0;
>
> fail:
> + av_free(pids);
> for(i = 0;i < s->nb_streams; i++) {
> st = s->streams[i];
> av_free(st->priv_data);
Regards.
--
FFmpeg = Fundamentalist and Faithful Mournful Pitiless Enigmatic Gargoyle
More information about the ffmpeg-devel
mailing list