[FFmpeg-devel] [PATCH] lavf: Add DICOM demuxer, lavc: Add DICOM decoder
Moritz Barsnick
barsnick at gmx.net
Wed Aug 21 19:09:52 EEST 2019
On Tue, Aug 20, 2019 at 20:53:43 +0530, Shivam wrote:
One more. Some more nitpicking around this. Please use valgrind with
all your samples and some demuxing and decoding command lines.
> +static int dicom_read_packet(AVFormatContext *s, AVPacket *pkt)
> +{
> + DICOMContext *dicom = s->priv_data;
> + int metadata = dicom->metadata, ret;
> + AVDictionary **st_md;
> + char *key, *value;
> + AVStream *st;
> + DataElement *de;
> +
> + if (s->nb_streams < 1) {
> + st = avformat_new_stream(s, NULL);
> + if (!st)
> + return AVERROR(ENOMEM);
> + st->codecpar->codec_id = AV_CODEC_ID_DICOM;
> + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
> + st->start_time = 0;
> + avpriv_set_pts_info(st, 64, 1, 1000);
> + if (dicom->window != -1)
> + st->codecpar->profile = dicom->window;
> + if (dicom->level != -1)
> + st->codecpar->level = dicom->level;
> + } else
> + st = s->streams[0];
> +
> + st_md = &st->metadata;
> + dicom->inheader = 0;
> + if (dicom->frame_nb > 1 && dicom->frame_nb <= dicom->nb_frames)
> + goto inside_pix_data;
> +
> + for (;;) {
> + ret = avio_feof(s->pb);
> + if (ret)
> + return AVERROR_EOF;
> +
> + de = alloc_de();
Allocation failure needs to be checked:
if (!de)
return AVERROR(ENOMEM);
> + ret = read_de_metainfo(s,de);
> + if (ret < 0)
> + goto exit;
> +
> + if (de->GroupNumber == PIXEL_GR_NB && de->ElementNumber == PIXELDATA_EL_NB) {
> + dicom->frame_size = de->VL / dicom->nb_frames;
> + set_dec_extradata(s, st);
> + inside_pix_data:
> + if (av_new_packet(pkt, dicom->frame_size) < 0)
> + return AVERROR(ENOMEM);
This leaks de. Instead:
if (av_new_packet(pkt, dicom->frame_size) < 0) {
ret = AVERROR(ENOMEM);
goto exit;
}
> + pkt->pos = avio_tell(s->pb);
> + pkt->stream_index = 0;
> + pkt->size = dicom->frame_size;
> + pkt->duration = dicom->delay;
> + ret = avio_read(s->pb, pkt->data, dicom->frame_size);
> + if (ret < 0) {
> + av_packet_unref(pkt);
> + goto exit;
> + }
> + dicom->frame_nb ++;
> + return ret;
This leaks everything (i.e. de and pkt). Instead:
dicom->frame_nb ++;
av_packet_unref(pkt);
goto exit;
> + } else if (de->GroupNumber == IMAGE_GR_NB || de->GroupNumber == MF_GR_NB) {
> + ret = read_de_valuefield(s, de);
> + if (ret < 0)
> + goto exit;
> + set_imagegroup_data(s, st, de);
> + set_multiframe_data(s, st, de);
> + } else {
> + if (metadata || de->VL == UNDEFINED_VL)
> + ret = read_de_valuefield(s, de);
> + else
> + ret = avio_skip(s->pb, de->VL); // skip other elements
> + if (ret < 0)
> + goto exit;
> + }
> + if (metadata) {
> + ret = dicom_dict_find_elem_info(de);
> + if (ret < 0)
> + goto end_de;
> + key = get_key_str(de);
> + value = get_val_str(de);
> + av_dict_set(st_md, key, value, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
> + }
> + end_de:
> + free_de(de);
> + }
> +exit:
> + free_de(de);
> + if (ret < 0)
> + return ret;
> + return AVERROR_EOF;
> +}
And, as mentioned, "goto exit" can probably be a simple "break", but
that's up to you to verify that it still does the right thing.
Cheers,
Moritz
More information about the ffmpeg-devel
mailing list