uint32_t i;
- int32_t audio_format, chunk_catalog_offset, number_of_chunks;
+ int32_t video_format, audio_format, chunk_catalog_offset, number_of_chunks;
AVRational fps;
char line[RPL_LINE_LENGTH];
av_dict_set(&s->metadata, "author" , line, 0);
// video headers
- vst = avformat_new_stream(s, NULL);
- if (!vst)
- return AVERROR(ENOMEM);
- vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
- vst->codecpar->codec_tag = read_line_and_int(pb, &error); // video format
- vst->codecpar->width = read_line_and_int(pb, &error); // video width
- vst->codecpar->height = read_line_and_int(pb, &error); // video height
- vst->codecpar->bits_per_coded_sample = read_line_and_int(pb, &error); // video bits per sample
- error |= read_line(pb, line, sizeof(line)); // video frames per second
- fps = read_fps(line, &error);
- avpriv_set_pts_info(vst, 32, fps.den, fps.num);
-
- // Figure out the video codec
- switch (vst->codecpar->codec_tag) {
+ video_format = read_line_and_int(pb, &error);
+ if (video_format) {
+ vst = avformat_new_stream(s, NULL);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codecpar->codec_tag = video_format;
+ vst->codecpar->width = read_line_and_int(pb, &error); // video width
+ vst->codecpar->height = read_line_and_int(pb, &error); // video height
+ vst->codecpar->bits_per_coded_sample = read_line_and_int(pb, &error); // video bits per sample
+
+ // Figure out the video codec
+ switch (vst->codecpar->codec_tag) {
#if 0
- case 122:
- vst->codecpar->codec_id = AV_CODEC_ID_ESCAPE122;
- break;
+ case 122:
+ vst->codecpar->codec_id = AV_CODEC_ID_ESCAPE122;
+ break;
#endif
- case 124:
- vst->codecpar->codec_id = AV_CODEC_ID_ESCAPE124;
- // The header is wrong here, at least sometimes
- vst->codecpar->bits_per_coded_sample = 16;
- break;
- case 130:
- vst->codecpar->codec_id = AV_CODEC_ID_ESCAPE130;
- break;
- default:
- avpriv_report_missing_feature(s, "Video format %s",
- av_fourcc2str(vst->codecpar->codec_tag));
- vst->codecpar->codec_id = AV_CODEC_ID_NONE;
+ case 124:
+ vst->codecpar->codec_id = AV_CODEC_ID_ESCAPE124;
+ // The header is wrong here, at least sometimes
+ vst->codecpar->bits_per_coded_sample = 16;
+ break;
+ case 130:
+ vst->codecpar->codec_id = AV_CODEC_ID_ESCAPE130;
+ break;
+ default:
+ avpriv_report_missing_feature(s, "Video format %s",
+ av_fourcc2str(vst->codecpar->codec_tag));
+ vst->codecpar->codec_id = AV_CODEC_ID_NONE;
+ }
+ } else {
+ for (i = 0; i < 3; i++)
+ error |= read_line(pb, line, sizeof(line));
}
+ error |= read_line(pb, line, sizeof(line)); // video frames per second
+ fps = read_fps(line, &error);
+ if (vst)
+ avpriv_set_pts_info(vst, 32, fps.den, fps.num);
+
// Audio headers
// ARMovie supports multiple audio tracks; I don't have any
ast->codecpar->channels = read_line_and_int(pb, &error); // number of audio channels
error |= read_line(pb, line, sizeof(line));
ast->codecpar->bits_per_coded_sample = read_int(line, &endptr, &error); // audio bits per sample
- strcpy(audio_type, endptr);
+ av_strlcpy(audio_type, endptr, RPL_LINE_LENGTH);
// At least one sample uses 0 for ADPCM, which is really 4 bits
// per sample.
if (ast->codecpar->bits_per_coded_sample == 0)
ast->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
break;
} else if (ast->codecpar->bits_per_coded_sample == 8) {
- if(strstr(audio_type, "unsigned") != NULL) {
+ if(av_stristr(audio_type, "unsigned") != NULL) {
ast->codecpar->codec_id = AV_CODEC_ID_PCM_U8;
break;
- } else if(strstr(audio_type, "linear") != NULL) {
+ } else if(av_stristr(audio_type, "linear") != NULL) {
ast->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
break;
} else {
error |= read_line(pb, line, sizeof(line));
}
+ if (s->nb_streams == 0)
+ return AVERROR_INVALIDDATA;
+
rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk
- if (rpl->frames_per_chunk > 1 && vst->codecpar->codec_tag != 124)
+ if (vst && rpl->frames_per_chunk > 1 && vst->codecpar->codec_tag != 124)
av_log(s, AV_LOG_WARNING,
"Don't know how to split frames for video format %s. "
"Video stream will be broken!\n", av_fourcc2str(vst->codecpar->codec_tag));
read_line_and_int(pb, &error); // (file index)
error |= read_line(pb, line, sizeof(line)); // offset to "helpful" sprite
error |= read_line(pb, line, sizeof(line)); // size of "helpful" sprite
- error |= read_line(pb, line, sizeof(line)); // offset to key frame list
+ if (vst) {
+ error |= read_line(pb, line, sizeof(line)); // offset to key frame list
+ vst->duration = number_of_chunks * rpl->frames_per_chunk;
+ }
// Read the index
avio_seek(pb, chunk_catalog_offset, SEEK_SET);
error = -1;
continue;
}
- av_add_index_entry(vst, offset, i * rpl->frames_per_chunk,
- video_size, rpl->frames_per_chunk, 0);
+ if (vst)
+ av_add_index_entry(vst, offset, i * rpl->frames_per_chunk,
+ video_size, rpl->frames_per_chunk, 0);
if (ast)
av_add_index_entry(ast, offset + video_size, total_audio_size,
audio_size, audio_size * 8, 0);
stream = s->streams[rpl->chunk_part];
- if (rpl->chunk_number >= stream->nb_index_entries)
+ if (rpl->chunk_number >= stream->internal->nb_index_entries)
return AVERROR_EOF;
- index_entry = &stream->index_entries[rpl->chunk_number];
+ index_entry = &stream->internal->index_entries[rpl->chunk_number];
if (rpl->frame_in_part == 0)
if (avio_seek(pb, index_entry->pos, SEEK_SET) < 0)
if (ret < 0)
return ret;
if (ret != frame_size) {
- av_packet_unref(pkt);
return AVERROR(EIO);
}
pkt->duration = 1;
if (ret < 0)
return ret;
if (ret != index_entry->size) {
- av_packet_unref(pkt);
return AVERROR(EIO);
}
return ret;
}
-AVInputFormat ff_rpl_demuxer = {
+const AVInputFormat ff_rpl_demuxer = {
.name = "rpl",
.long_name = NULL_IF_CONFIG_SMALL("RPL / ARMovie"),
.priv_data_size = sizeof(RPLContext),