Mercurial > libavformat.hg
comparison utils.c @ 5200:cd884511ec8b libavformat
Make packet interleaving in the muxer not scan through the whole
buffer when simply appending at the end works.
Much faster if one stream ends prematurely.
Fixes issue1379.
author | michael |
---|---|
date | Wed, 16 Sep 2009 00:59:15 +0000 |
parents | fc6e05b7709d |
children | 12bd8561aed1 |
comparison
equal
deleted
inserted
replaced
5199:fc6e05b7709d | 5200:cd884511ec8b |
---|---|
2655 this_pktl = av_mallocz(sizeof(AVPacketList)); | 2655 this_pktl = av_mallocz(sizeof(AVPacketList)); |
2656 this_pktl->pkt= *pkt; | 2656 this_pktl->pkt= *pkt; |
2657 pkt->destruct= NULL; // do not free original but only the copy | 2657 pkt->destruct= NULL; // do not free original but only the copy |
2658 av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory | 2658 av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory |
2659 | 2659 |
2660 if(!s->packet_buffer_end || compare(s, &s->packet_buffer_end->pkt, pkt)){ | |
2660 next_point = &s->packet_buffer; | 2661 next_point = &s->packet_buffer; |
2661 while(*next_point){ | 2662 while(*next_point){ |
2662 if(compare(s, &(*next_point)->pkt, pkt)) | 2663 if(compare(s, &(*next_point)->pkt, pkt)) |
2663 break; | 2664 break; |
2664 next_point= &(*next_point)->next; | 2665 next_point= &(*next_point)->next; |
2665 } | 2666 } |
2667 }else{ | |
2668 next_point = &(s->packet_buffer_end->next); | |
2669 assert(!*next_point); | |
2670 } | |
2666 this_pktl->next= *next_point; | 2671 this_pktl->next= *next_point; |
2672 | |
2673 if(!*next_point) | |
2674 s->packet_buffer_end= this_pktl; | |
2675 | |
2667 *next_point= this_pktl; | 2676 *next_point= this_pktl; |
2677 | |
2678 s->streams[pkt->stream_index]->num_in_packet_buffer++; | |
2668 } | 2679 } |
2669 | 2680 |
2670 int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt) | 2681 int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt) |
2671 { | 2682 { |
2672 AVStream *st = s->streams[ pkt ->stream_index]; | 2683 AVStream *st = s->streams[ pkt ->stream_index]; |
2681 } | 2692 } |
2682 | 2693 |
2683 int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){ | 2694 int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){ |
2684 AVPacketList *pktl; | 2695 AVPacketList *pktl; |
2685 int stream_count=0; | 2696 int stream_count=0; |
2686 int streams[MAX_STREAMS]; | 2697 int i; |
2687 | 2698 |
2688 if(pkt){ | 2699 if(pkt){ |
2689 ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts); | 2700 ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts); |
2690 } | 2701 } |
2691 | 2702 |
2692 memset(streams, 0, sizeof(streams)); | 2703 for(i=0; i < s->nb_streams; i++) |
2693 pktl= s->packet_buffer; | 2704 stream_count+= !!s->streams[i]->num_in_packet_buffer; |
2694 while(pktl){ | |
2695 //av_log(s, AV_LOG_DEBUG, "show st:%d dts:%"PRId64"\n", pktl->pkt.stream_index, pktl->pkt.dts); | |
2696 if(streams[ pktl->pkt.stream_index ] == 0) | |
2697 stream_count++; | |
2698 streams[ pktl->pkt.stream_index ]++; | |
2699 pktl= pktl->next; | |
2700 } | |
2701 | 2705 |
2702 if(stream_count && (s->nb_streams == stream_count || flush)){ | 2706 if(stream_count && (s->nb_streams == stream_count || flush)){ |
2703 pktl= s->packet_buffer; | 2707 pktl= s->packet_buffer; |
2704 *out= pktl->pkt; | 2708 *out= pktl->pkt; |
2705 | 2709 |
2706 s->packet_buffer= pktl->next; | 2710 s->packet_buffer= pktl->next; |
2711 if(!s->packet_buffer) | |
2712 s->packet_buffer_end= NULL; | |
2713 | |
2714 s->streams[out->stream_index]->num_in_packet_buffer--; | |
2707 av_freep(&pktl); | 2715 av_freep(&pktl); |
2708 return 1; | 2716 return 1; |
2709 }else{ | 2717 }else{ |
2710 av_init_packet(out); | 2718 av_init_packet(out); |
2711 return 0; | 2719 return 0; |