2,553
社区成员




int fp_write = -1;
int write_packet(void *opaque, uint8_t *buff, int buf_size)
{
int sentbyte = -1;
if (fp_write != -1)
{
sentbyte = write(fp_write, buff, buf_size);
}
return sentbyte;
}
int main(void)
{
int ret = 0, i;
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
AVIOContext *avio_out = NULL;
AVPacket pkt;
#define USE_H264BSF
#ifdef USE_H264BSF
AVBitStreamFilterContext *h264bsfc = NULL;
int video_index = -1;
#endif
char *in_filename, *out_filename;
unsigned char *out_buff = NULL;
in_filename = "/tmp/media/mp4.mp4";
out_filename = "/tmp/media/test_video.ts";
av_register_all();
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0)
{
fprintf(stderr, "Could not open input file '%s'", in_filename);
goto end;
}
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0)
{
fprintf(stderr, "Failed to retrieve input stream information");
goto end;
}
/* Allocate buffer for output data */
out_buff = (unsigned char *)av_malloc(OUT_BUFF_LEN);
printf("out_buff: 0x%p\n", out_buff);
if (!out_buff)
{
fprintf(stderr, "av_malloc error\n");
goto end;
}
/* Output file for testing */
fp_write = open(out_filename, O_WRONLY | O_CREAT);
if (fp_write == -1)
{
perror("open");
goto end;
}
/* Allocate avformat */
ofmt_ctx = avformat_alloc_context();
if (!ofmt_ctx)
{
fprintf(stderr, "Could not create output context\n");
ret = AVERROR_UNKNOWN;
goto end;
}
ofmt_ctx->oformat = av_guess_format("mpegts", NULL, NULL);
if (!ofmt_ctx->oformat)
{
fprintf(stderr, "Could not set output format\n");
ret = AVERROR_UNKNOWN;
goto end;
}
/* Allocate avio context */
avio_out = avio_alloc_context(out_buff, OUT_BUFF_LEN, 1, NULL, NULL, write_packet, NULL);
if (!avio_out)
{
fprintf(stderr, "Could not create avio context\n");
ret = AVERROR_UNKNOWN;
goto end;
}
/* AVIO struct */
ofmt_ctx->pb = avio_out;
ofmt_ctx->flags = AVFMT_FLAG_CUSTOM_IO;
for (i = 0; i < ifmt_ctx->nb_streams; i++)
{
AVStream *in_stream = ifmt_ctx->streams[i];
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
if (!out_stream) {
fprintf(stderr, "Failed allocating output stream\n");
ret = AVERROR_UNKNOWN;
goto end;
}
ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
if (ret < 0) {
fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
goto end;
}
out_stream->codec->codec_tag = 0;
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
{
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
#ifdef USE_H264BSF
/* mark video index */
if (out_stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
video_index = i;
}
#endif
}
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0)
{
fprintf(stderr, "Error occurred when opening output file\n");
goto end;
}
#ifdef USE_H264BSF
h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
#endif
while (1) {
AVStream *in_stream, *out_stream;
ret = av_read_frame(ifmt_ctx, &pkt);
if (ret < 0)
{
av_packet_unref(&pkt);
break;
}
#ifdef USE_H264BSF
if (pkt.stream_index == video_index)
{
av_bitstream_filter_filter(h264bsfc, ifmt_ctx->streams[video_index]->codec,
NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
}
#endif
in_stream = ifmt_ctx->streams[pkt.stream_index];
out_stream = ofmt_ctx->streams[pkt.stream_index];
/* copy packet */
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;
ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
if (ret < 0) {
fprintf(stderr, "Error muxing packet\n");
av_packet_unref(&pkt);
break;
}
av_packet_unref(&pkt);
}
av_write_trailer(ofmt_ctx);
end:
avformat_close_input(&ifmt_ctx);
/* close output */
if (!avio_out && out_buff)
{
av_freep(&out_buff);
}
if (avio_out)
{
av_freep(&avio_out->buffer);
av_freep(&avio_out);
}
if (fp_write != -1)
{
close(fp_write);
}
avformat_free_context(ofmt_ctx);
#ifdef USE_H264BSF
av_bitstream_filter_close(h264bsfc);
#endif
if (ret < 0 && ret != AVERROR_EOF)
{
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
return 1;
}
return 0;
}