On 12/04/2014 12:36 AM, wm4 wrote: > On Wed, 3 Dec 2014 17:58:57 +0530 > anshul.ffm...@gmail.com wrote: > >> From: Nicolas George <geo...@nsup.org> >> >> --- >> doc/indevs.texi | 9 ++++++ >> libavdevice/lavfi.c | 80 >> +++++++++++++++++++++++++++++++++++++++++++++++++---- >> 2 files changed, 84 insertions(+), 5 deletions(-) >> >> diff --git a/doc/indevs.texi b/doc/indevs.texi >> index 5d2a308..f31e2e3 100644 >> --- a/doc/indevs.texi >> +++ b/doc/indevs.texi >> @@ -494,6 +494,9 @@ number starting from 0 corresponding to the mapped input >> stream >> generated by the device. >> The first unlabelled output is automatically assigned to the "out0" >> label, but all the others need to be specified explicitly. >> +The suffix "+subcc" can be appended to the output label to create an extra >> +stream with the closed captions packets attached to that output >> +(experimental). >> >> If not specified defaults to the filename specified for the input >> device. >> @@ -541,6 +544,12 @@ Read an audio stream and a video stream and play it >> back with >> ffplay -f lavfi "movie=test.avi[out0];amovie=test.wav[out1]" >> @end example >> >> +@item >> +Dump decoded frames to images and closed captions to a file (experimental): >> +@example >> +ffmpeg -f lavfi -i "movie=test.ts[out0+subcc]" -map v frame%08d.png -map s >> -c copy -f rawvideo subcc.bin >> +@end example >> + >> @end itemize >> >> @section libcdio >> diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c >> index 1398ece..bc45117 100644 >> --- a/libavdevice/lavfi.c >> +++ b/libavdevice/lavfi.c >> @@ -51,7 +51,10 @@ typedef struct { >> int *sink_stream_map; >> int *sink_eof; >> int *stream_sink_map; >> + int *sink_stream_subcc_map; >> AVFrame *decoded_frame; >> + int nb_sinks; >> + AVPacket subcc_packet; >> } LavfiContext; >> >> static int *create_all_formats(int n) >> @@ -82,6 +85,7 @@ av_cold static int lavfi_read_close(AVFormatContext *avctx) >> av_freep(&lavfi->sink_stream_map); >> av_freep(&lavfi->sink_eof); >> av_freep(&lavfi->stream_sink_map); >> + av_freep(&lavfi->sink_stream_subcc_map); >> av_freep(&lavfi->sinks); >> avfilter_graph_free(&lavfi->graph); >> av_frame_free(&lavfi->decoded_frame); >> @@ -89,6 +93,27 @@ av_cold static int lavfi_read_close(AVFormatContext >> *avctx) >> return 0; >> } >> >> +static int create_subcc_streams(AVFormatContext *avctx) >> +{ >> + LavfiContext *lavfi = avctx->priv_data; >> + AVStream *st; >> + int stream_idx, sink_idx; >> + >> + for (stream_idx = 0; stream_idx < lavfi->nb_sinks; stream_idx++) { >> + sink_idx = lavfi->stream_sink_map[stream_idx]; >> + if (lavfi->sink_stream_subcc_map[sink_idx]) { >> + lavfi->sink_stream_subcc_map[sink_idx] = avctx->nb_streams; >> + if (!(st = avformat_new_stream(avctx, NULL))) >> + return AVERROR(ENOMEM); >> + st->codec->codec_id = AV_CODEC_ID_EIA_608; >> + st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; >> + } else { >> + lavfi->sink_stream_subcc_map[sink_idx] = -1; >> + } >> + } >> + return 0; >> +} >> + >> av_cold static int lavfi_read_header(AVFormatContext *avctx) >> { >> LavfiContext *lavfi = avctx->priv_data; >> @@ -153,6 +178,7 @@ av_cold static int lavfi_read_header(AVFormatContext >> *avctx) >> >> /* count the outputs */ >> for (n = 0, inout = output_links; inout; n++, inout = inout->next); >> + lavfi->nb_sinks = n; >> >> if (!(lavfi->sink_stream_map = av_malloc(sizeof(int) * n))) >> FAIL(AVERROR(ENOMEM)); >> @@ -160,6 +186,8 @@ av_cold static int lavfi_read_header(AVFormatContext >> *avctx) >> FAIL(AVERROR(ENOMEM)); >> if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n))) >> FAIL(AVERROR(ENOMEM)); >> + if (!(lavfi->sink_stream_subcc_map = av_malloc(sizeof(int) * n))) >> + FAIL(AVERROR(ENOMEM)); >> >> for (i = 0; i < n; i++) >> lavfi->stream_sink_map[i] = -1; >> @@ -167,10 +195,10 @@ av_cold static int lavfi_read_header(AVFormatContext >> *avctx) >> /* parse the output link names - they need to be of the form out0, >> out1, ... >> * create a mapping between them and the streams */ >> for (i = 0, inout = output_links; inout; i++, inout = inout->next) { >> - int stream_idx; >> + int stream_idx, use_subcc = 0; >> if (!strcmp(inout->name, "out")) >> stream_idx = 0; >> - else if (sscanf(inout->name, "out%d\n", &stream_idx) != 1) { >> + else if (sscanf(inout->name, "out%d+subcc%n\n", &stream_idx, >> &use_subcc) != 1) { >> av_log(avctx, AV_LOG_ERROR, >> "Invalid outpad name '%s'\n", inout->name); >> FAIL(AVERROR(EINVAL)); >> @@ -192,6 +220,7 @@ av_cold static int lavfi_read_header(AVFormatContext >> *avctx) >> } >> lavfi->sink_stream_map[i] = stream_idx; >> lavfi->stream_sink_map[stream_idx] = i; >> + lavfi->sink_stream_subcc_map[stream_idx] = !!use_subcc; >> } >> >> /* for each open output create a corresponding stream */ >> @@ -203,7 +232,7 @@ av_cold static int lavfi_read_header(AVFormatContext >> *avctx) >> } >> >> /* create a sink for each output and connect them to the graph */ >> - lavfi->sinks = av_malloc_array(avctx->nb_streams, >> sizeof(AVFilterContext *)); >> + lavfi->sinks = av_malloc_array(lavfi->nb_sinks, sizeof(AVFilterContext >> *)); >> if (!lavfi->sinks) >> FAIL(AVERROR(ENOMEM)); >> >> @@ -267,7 +296,7 @@ av_cold static int lavfi_read_header(AVFormatContext >> *avctx) >> } >> >> /* fill each stream with the information in the corresponding sink */ >> - for (i = 0; i < avctx->nb_streams; i++) { >> + for (i = 0; i < lavfi->nb_sinks; i++) { >> AVFilterLink *link = >> lavfi->sinks[lavfi->stream_sink_map[i]]->inputs[0]; >> AVStream *st = avctx->streams[i]; >> st->codec->codec_type = link->type; >> @@ -298,6 +327,9 @@ av_cold static int lavfi_read_header(AVFormatContext >> *avctx) >> } >> } >> >> + if ((ret = create_subcc_streams(avctx)) < 0) >> + FAIL(ret); >> + >> if (!(lavfi->decoded_frame = av_frame_alloc())) >> FAIL(AVERROR(ENOMEM)); >> >> @@ -310,6 +342,30 @@ end: >> return ret; >> } >> >> +static int create_subcc_packet(AVFormatContext *avctx, AVFrame *frame, >> + int sink_idx) >> +{ >> + LavfiContext *lavfi = avctx->priv_data; >> + AVFrameSideData *sd; >> + int stream_idx, i, ret; >> + >> + if ((stream_idx = lavfi->sink_stream_subcc_map[sink_idx]) < 0) >> + return 0; >> + for (i = 0; i < frame->nb_side_data; i++) >> + if (frame->side_data[i]->type == AV_FRAME_DATA_A53_CC) >> + break; >> + if (i >= frame->nb_side_data) >> + return 0; >> + sd = frame->side_data[i]; >> + if ((ret = av_new_packet(&lavfi->subcc_packet, sd->size)) < 0) >> + return ret; >> + memcpy(lavfi->subcc_packet.data, sd->data, sd->size); >> + lavfi->subcc_packet.stream_index = stream_idx; >> + lavfi->subcc_packet.pts = frame->pts; >> + lavfi->subcc_packet.pos = av_frame_get_pkt_pos(frame); >> + return 0; >> +} >> + >> static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) >> { >> LavfiContext *lavfi = avctx->priv_data; >> @@ -321,9 +377,17 @@ static int lavfi_read_packet(AVFormatContext *avctx, >> AVPacket *pkt) >> int ret, i; >> int size = 0; >> >> + if (lavfi->subcc_packet.size) { >> + *pkt = lavfi->subcc_packet; >> + av_init_packet(&lavfi->subcc_packet); >> + lavfi->subcc_packet.size = 0; >> + lavfi->subcc_packet.data = NULL; >> + return pkt->size; >> + } >> + >> /* iterate through all the graph sinks. Select the sink with the >> * minimum PTS */ >> - for (i = 0; i < avctx->nb_streams; i++) { >> + for (i = 0; i < lavfi->nb_sinks; i++) { >> AVRational tb = lavfi->sinks[i]->inputs[0]->time_base; >> double d; >> int ret; >> @@ -397,6 +461,12 @@ static int lavfi_read_packet(AVFormatContext *avctx, >> AVPacket *pkt) >> av_bprint_finalize(&meta_buf, NULL); >> } >> >> + if ((ret = create_subcc_packet(avctx, frame, min_pts_sink_idx)) < 0) { >> + av_frame_unref(frame); >> + av_packet_unref(pkt); >> + return ret; >> + } >> + >> pkt->stream_index = stream_idx; >> pkt->pts = frame->pts; >> pkt->pos = av_frame_get_pkt_pos(frame); > > Why is this in libavdevice? > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Dont know why its here, but this is most required part to extract cc from h264 user data.
It may be because -f v4l2 is in device, Here input parameter is not considered in normal way. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel