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;