Video quality lost when converting from .ogg to .mp4

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Video quality lost when converting from .ogg to .mp4

william.l.metcalf
Hello all,

I have written a gstreamer C application to convert a .ogg to .mp4
file.  The application is successful at converting the video and audio,
but the video produced after the conversion is of much lower quality
than the original video ( the audio converts with basically no loss I
can see).  I figure that some loss in video is to be expected, but I was
wondering what gstreamer modules might be good for helping lower the
loss in video quality.  Below is a snippet of my code that shows the
pipeline I used to convert the file.

Thank you in advance for your help.

int main (int argc, char *argv[])
{
     gst_init(&argc, &argv);

     AV = 0;

     loop = g_main_loop_new(NULL, FALSE);

     /* Create elements */
     pipeline            = gst_pipeline_new("audio-player");

     /* Element for reading in a file */
     source                = gst_element_factory_make("filesrc",
"file-source");

     /* OGG elements */
     oggdemuxer            = gst_element_factory_make("oggdemux",
"ogg-demuxer");
     vorbis_decoder        = gst_element_factory_make("vorbisdec",
"vorbis-decoder");
     theora_decoder        = gst_element_factory_make("theoradec",
"theora-decoder");

     /* MP4 elements */
     audio_encoder        = gst_element_factory_make("faac", "aac-encoder");
     video_encoder        = gst_element_factory_make("ffenc_mpeg4",
"avc-encoder");
     mp4_muxer            = gst_element_factory_make("qtmux", "mp4-muxer");

     /* Audio/Video elements */
     video_converter        =
gst_element_factory_make("ffmpegcolorspace", "video-converter");
     videosink            = gst_element_factory_make("autovideosink",
"video-sink");
     video_scale            = gst_element_factory_make("videoscale",
"video-scale");
     video_rate            = gst_element_factory_make("videorate",
"video-rate");
     audio_resample        = gst_element_factory_make("audioresample",
"audio-resample");
     audio_rate            = gst_element_factory_make("audiorate",
"audio-rate");
     audiosink            = gst_element_factory_make("autoaudiosink",
"audio-sink");
     audio_converter        = gst_element_factory_make("audioconvert",
"audio-converter");

     /* Queues */
     video_queue            = gst_element_factory_make("queue",
"video-queue");
     audio_queue            = gst_element_factory_make("queue",
"audio-queue");
     video_out_queue        = gst_element_factory_make("queue",
"video-out-queue");
     audio_out_queue        = gst_element_factory_make("queue",
"audio-out-queue");

     /* Element to write to the file */
     filesink                = gst_element_factory_make("filesink",
"file-sink");

     /* Make sure we were able to create all of the elements*/
     if(!pipeline || !source || !oggdemuxer || !vorbis_decoder ||
!theora_decoder || !audio_encoder || !video_encoder || !mp4_muxer ||
!audio_converter || !video_converter || !audio_resample || !audio_rate
|| !videosink || !audiosink || !video_queue || !audio_queue ||
!video_out_queue || !audio_out_queue || !video_scale || !video_rate ||
!filesink )
     {
         g_printerr("One ore more elements could not be created.
Exiting.\n");
         return -1;
     }

     /* Input file */
     g_object_set(G_OBJECT(source), "location", "c:\\video(1080p).ogg",
NULL);
     g_object_set(G_OBJECT(filesink), "location",
"c:\\Encoder_Output\\video(encoded from ogg).mp4", NULL);

     /* Add a message handler from pipeline bus */
     bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
     gst_bus_add_watch(bus, bus_call, loop);
     gst_object_unref(bus);

     /* add elements to the pipeline */
     gst_bin_add_many(GST_BIN(pipeline), source, oggdemuxer,
video_queue, theora_decoder, video_converter, video_scale, video_rate,
video_encoder, video_out_queue, audio_queue, vorbis_decoder,
audio_converter, audio_resample, audio_rate, audio_encoder,
audio_out_queue, mp4_muxer, filesink, NULL);

     /* link the elements together */
     res = gst_element_link(source, oggdemuxer);
     if(!res)
     {
         g_printerr("There was a problem linking filesrc to oggdemux.\n");
         return 1;
     }

     /* video_queue -> theoradec -> ffmpegcolorspace -> ffenc_mpeg4 ->
video_out_queue ~> qtmux */
     res = gst_element_link_many(video_queue, theora_decoder,
video_converter, video_scale, video_rate, video_encoder,
video_out_queue, NULL);
     if(!res)
     {
         g_printerr("There was a problem linking video elements.\n");
         return 1;
     }
     //link_video_caps(video_scale, video_encoder, 854, 480, 25, 1);

     /* queue_audio -> vorbisdec -> audioconvert -> faac ->
audio_out_queue ~> qtmux */
     res = gst_element_link_many(audio_queue, vorbis_decoder,
audio_converter, audio_resample, audio_rate, audio_encoder,
audio_out_queue, NULL);
     if(!res)
     {
         g_printerr("There was a problem linking the audio elements.\n");
         return 1;
     }
     g_signal_connect(oggdemuxer, "pad-added", G_CALLBACK(on_pad_added),
NULL);

     /* qtmux -> filesink */
     res = gst_element_link(mp4_muxer, filesink);
     if(!res)
     {
         g_printerr("There was a problem linking qtmux to filesink.\n");
         return 1;
     }

     link_video_to_multiplexer(video_out_queue, mp4_muxer);
     link_audio_to_multiplexer(audio_out_queue, mp4_muxer);


     /* Set the pipeline stat to play and start the main loop*/
     g_print("Starting the pipeline\n");
     gst_element_set_state(pipeline, GST_STATE_PLAYING);
     g_main_loop_run(loop);

     /* We are done now, do a little bit of cleaning up */
     g_print("Stopping the pipeline.\n");
     gst_element_set_state(pipeline, GST_STATE_NULL);
     gst_object_unref(GST_OBJECT(pipeline));

     return 0;
}
_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Video quality lost when converting from .ogg to .mp4

Trever Fischer
On Monday, June 06, 2011 10:46:55 AM William Metcalf wrote:

> Hello all,
>
> I have written a gstreamer C application to convert a .ogg to .mp4
> file.  The application is successful at converting the video and audio,
> but the video produced after the conversion is of much lower quality
> than the original video ( the audio converts with basically no loss I
> can see).  I figure that some loss in video is to be expected, but I was
> wondering what gstreamer modules might be good for helping lower the
> loss in video quality.  Below is a snippet of my code that shows the
> pipeline I used to convert the file.
Converting from a lossy format to a lossy format almost always causes a
reduction in quality. No real way to avoid that.

>
> Thank you in advance for your help.
>
> int main (int argc, char *argv[])
> {
>      gst_init(&argc, &argv);
>
>      AV = 0;
>
>      loop = g_main_loop_new(NULL, FALSE);
>
>      /* Create elements */
>      pipeline            = gst_pipeline_new("audio-player");
>
>      /* Element for reading in a file */
>      source                = gst_element_factory_make("filesrc",
> "file-source");
>
>      /* OGG elements */
>      oggdemuxer            = gst_element_factory_make("oggdemux",
> "ogg-demuxer");
>      vorbis_decoder        = gst_element_factory_make("vorbisdec",
> "vorbis-decoder");
>      theora_decoder        = gst_element_factory_make("theoradec",
> "theora-decoder");
>
>      /* MP4 elements */
>      audio_encoder        = gst_element_factory_make("faac",
> "aac-encoder"); video_encoder        =
> gst_element_factory_make("ffenc_mpeg4", "avc-encoder");
>      mp4_muxer            = gst_element_factory_make("qtmux", "mp4-muxer");
>
>      /* Audio/Video elements */
>      video_converter        =
> gst_element_factory_make("ffmpegcolorspace", "video-converter");
>      videosink            = gst_element_factory_make("autovideosink",
> "video-sink");
>      video_scale            = gst_element_factory_make("videoscale",
> "video-scale");
>      video_rate            = gst_element_factory_make("videorate",
> "video-rate");
>      audio_resample        = gst_element_factory_make("audioresample",
> "audio-resample");
>      audio_rate            = gst_element_factory_make("audiorate",
> "audio-rate");
>      audiosink            = gst_element_factory_make("autoaudiosink",
> "audio-sink");
>      audio_converter        = gst_element_factory_make("audioconvert",
> "audio-converter");
>
>      /* Queues */
>      video_queue            = gst_element_factory_make("queue",
> "video-queue");
>      audio_queue            = gst_element_factory_make("queue",
> "audio-queue");
>      video_out_queue        = gst_element_factory_make("queue",
> "video-out-queue");
>      audio_out_queue        = gst_element_factory_make("queue",
> "audio-out-queue");
>
>      /* Element to write to the file */
>      filesink                = gst_element_factory_make("filesink",
> "file-sink");
>
>      /* Make sure we were able to create all of the elements*/
>      if(!pipeline || !source || !oggdemuxer || !vorbis_decoder ||
> !theora_decoder || !audio_encoder || !video_encoder || !mp4_muxer ||
> !audio_converter || !video_converter || !audio_resample || !audio_rate
>
> || !videosink || !audiosink || !video_queue || !audio_queue ||
>
> !video_out_queue || !audio_out_queue || !video_scale || !video_rate ||
> !filesink )
>      {
>          g_printerr("One ore more elements could not be created.
> Exiting.\n");
>          return -1;
>      }
>
>      /* Input file */
>      g_object_set(G_OBJECT(source), "location", "c:\\video(1080p).ogg",
> NULL);
>      g_object_set(G_OBJECT(filesink), "location",
> "c:\\Encoder_Output\\video(encoded from ogg).mp4", NULL);
>
>      /* Add a message handler from pipeline bus */
>      bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
>      gst_bus_add_watch(bus, bus_call, loop);
>      gst_object_unref(bus);
>
>      /* add elements to the pipeline */
>      gst_bin_add_many(GST_BIN(pipeline), source, oggdemuxer,
> video_queue, theora_decoder, video_converter, video_scale, video_rate,
> video_encoder, video_out_queue, audio_queue, vorbis_decoder,
> audio_converter, audio_resample, audio_rate, audio_encoder,
> audio_out_queue, mp4_muxer, filesink, NULL);
>
>      /* link the elements together */
>      res = gst_element_link(source, oggdemuxer);
>      if(!res)
>      {
>          g_printerr("There was a problem linking filesrc to oggdemux.\n");
>          return 1;
>      }
>
>      /* video_queue -> theoradec -> ffmpegcolorspace -> ffenc_mpeg4 ->
> video_out_queue ~> qtmux */
>      res = gst_element_link_many(video_queue, theora_decoder,
> video_converter, video_scale, video_rate, video_encoder,
> video_out_queue, NULL);
>      if(!res)
>      {
>          g_printerr("There was a problem linking video elements.\n");
>          return 1;
>      }
>      //link_video_caps(video_scale, video_encoder, 854, 480, 25, 1);
>
>      /* queue_audio -> vorbisdec -> audioconvert -> faac ->
> audio_out_queue ~> qtmux */
>      res = gst_element_link_many(audio_queue, vorbis_decoder,
> audio_converter, audio_resample, audio_rate, audio_encoder,
> audio_out_queue, NULL);
>      if(!res)
>      {
>          g_printerr("There was a problem linking the audio elements.\n");
>          return 1;
>      }
>      g_signal_connect(oggdemuxer, "pad-added", G_CALLBACK(on_pad_added),
> NULL);
>
>      /* qtmux -> filesink */
>      res = gst_element_link(mp4_muxer, filesink);
>      if(!res)
>      {
>          g_printerr("There was a problem linking qtmux to filesink.\n");
>          return 1;
>      }
>
>      link_video_to_multiplexer(video_out_queue, mp4_muxer);
>      link_audio_to_multiplexer(audio_out_queue, mp4_muxer);
>
>
>      /* Set the pipeline stat to play and start the main loop*/
>      g_print("Starting the pipeline\n");
>      gst_element_set_state(pipeline, GST_STATE_PLAYING);
>      g_main_loop_run(loop);
>
>      /* We are done now, do a little bit of cleaning up */
>      g_print("Stopping the pipeline.\n");
>      gst_element_set_state(pipeline, GST_STATE_NULL);
>      gst_object_unref(GST_OBJECT(pipeline));
>
>      return 0;
> }
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Video quality lost when converting from .ogg to .mp4

william.l.metcalf
Thank you for the tip.  I was able to get a better quality video by
changing the bit rate property of the video encoder module from its
default 300 kbps to more closely match the bit rate of the .ogg file I
am converting from.

On 6/6/2011 1:03 PM, Trever Fischer wrote:

> On Monday, June 06, 2011 10:46:55 AM William Metcalf wrote:
>> Hello all,
>>
>> I have written a gstreamer C application to convert a .ogg to .mp4
>> file.  The application is successful at converting the video and audio,
>> but the video produced after the conversion is of much lower quality
>> than the original video ( the audio converts with basically no loss I
>> can see).  I figure that some loss in video is to be expected, but I was
>> wondering what gstreamer modules might be good for helping lower the
>> loss in video quality.  Below is a snippet of my code that shows the
>> pipeline I used to convert the file.
> Converting from a lossy format to a lossy format almost always causes a
> reduction in quality. No real way to avoid that.
>> Thank you in advance for your help.
>>
>> int main (int argc, char *argv[])
>> {
>>       gst_init(&argc,&argv);
>>
>>       AV = 0;
>>
>>       loop = g_main_loop_new(NULL, FALSE);
>>
>>       /* Create elements */
>>       pipeline            = gst_pipeline_new("audio-player");
>>
>>       /* Element for reading in a file */
>>       source                = gst_element_factory_make("filesrc",
>> "file-source");
>>
>>       /* OGG elements */
>>       oggdemuxer            = gst_element_factory_make("oggdemux",
>> "ogg-demuxer");
>>       vorbis_decoder        = gst_element_factory_make("vorbisdec",
>> "vorbis-decoder");
>>       theora_decoder        = gst_element_factory_make("theoradec",
>> "theora-decoder");
>>
>>       /* MP4 elements */
>>       audio_encoder        = gst_element_factory_make("faac",
>> "aac-encoder"); video_encoder        =
>> gst_element_factory_make("ffenc_mpeg4", "avc-encoder");
>>       mp4_muxer            = gst_element_factory_make("qtmux", "mp4-muxer");
>>
>>       /* Audio/Video elements */
>>       video_converter        =
>> gst_element_factory_make("ffmpegcolorspace", "video-converter");
>>       videosink            = gst_element_factory_make("autovideosink",
>> "video-sink");
>>       video_scale            = gst_element_factory_make("videoscale",
>> "video-scale");
>>       video_rate            = gst_element_factory_make("videorate",
>> "video-rate");
>>       audio_resample        = gst_element_factory_make("audioresample",
>> "audio-resample");
>>       audio_rate            = gst_element_factory_make("audiorate",
>> "audio-rate");
>>       audiosink            = gst_element_factory_make("autoaudiosink",
>> "audio-sink");
>>       audio_converter        = gst_element_factory_make("audioconvert",
>> "audio-converter");
>>
>>       /* Queues */
>>       video_queue            = gst_element_factory_make("queue",
>> "video-queue");
>>       audio_queue            = gst_element_factory_make("queue",
>> "audio-queue");
>>       video_out_queue        = gst_element_factory_make("queue",
>> "video-out-queue");
>>       audio_out_queue        = gst_element_factory_make("queue",
>> "audio-out-queue");
>>
>>       /* Element to write to the file */
>>       filesink                = gst_element_factory_make("filesink",
>> "file-sink");
>>
>>       /* Make sure we were able to create all of the elements*/
>>       if(!pipeline || !source || !oggdemuxer || !vorbis_decoder ||
>> !theora_decoder || !audio_encoder || !video_encoder || !mp4_muxer ||
>> !audio_converter || !video_converter || !audio_resample || !audio_rate
>>
>> || !videosink || !audiosink || !video_queue || !audio_queue ||
>>
>> !video_out_queue || !audio_out_queue || !video_scale || !video_rate ||
>> !filesink )
>>       {
>>           g_printerr("One ore more elements could not be created.
>> Exiting.\n");
>>           return -1;
>>       }
>>
>>       /* Input file */
>>       g_object_set(G_OBJECT(source), "location", "c:\\video(1080p).ogg",
>> NULL);
>>       g_object_set(G_OBJECT(filesink), "location",
>> "c:\\Encoder_Output\\video(encoded from ogg).mp4", NULL);
>>
>>       /* Add a message handler from pipeline bus */
>>       bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
>>       gst_bus_add_watch(bus, bus_call, loop);
>>       gst_object_unref(bus);
>>
>>       /* add elements to the pipeline */
>>       gst_bin_add_many(GST_BIN(pipeline), source, oggdemuxer,
>> video_queue, theora_decoder, video_converter, video_scale, video_rate,
>> video_encoder, video_out_queue, audio_queue, vorbis_decoder,
>> audio_converter, audio_resample, audio_rate, audio_encoder,
>> audio_out_queue, mp4_muxer, filesink, NULL);
>>
>>       /* link the elements together */
>>       res = gst_element_link(source, oggdemuxer);
>>       if(!res)
>>       {
>>           g_printerr("There was a problem linking filesrc to oggdemux.\n");
>>           return 1;
>>       }
>>
>>       /* video_queue ->  theoradec ->  ffmpegcolorspace ->  ffenc_mpeg4 ->
>> video_out_queue ~>  qtmux */
>>       res = gst_element_link_many(video_queue, theora_decoder,
>> video_converter, video_scale, video_rate, video_encoder,
>> video_out_queue, NULL);
>>       if(!res)
>>       {
>>           g_printerr("There was a problem linking video elements.\n");
>>           return 1;
>>       }
>>       //link_video_caps(video_scale, video_encoder, 854, 480, 25, 1);
>>
>>       /* queue_audio ->  vorbisdec ->  audioconvert ->  faac ->
>> audio_out_queue ~>  qtmux */
>>       res = gst_element_link_many(audio_queue, vorbis_decoder,
>> audio_converter, audio_resample, audio_rate, audio_encoder,
>> audio_out_queue, NULL);
>>       if(!res)
>>       {
>>           g_printerr("There was a problem linking the audio elements.\n");
>>           return 1;
>>       }
>>       g_signal_connect(oggdemuxer, "pad-added", G_CALLBACK(on_pad_added),
>> NULL);
>>
>>       /* qtmux ->  filesink */
>>       res = gst_element_link(mp4_muxer, filesink);
>>       if(!res)
>>       {
>>           g_printerr("There was a problem linking qtmux to filesink.\n");
>>           return 1;
>>       }
>>
>>       link_video_to_multiplexer(video_out_queue, mp4_muxer);
>>       link_audio_to_multiplexer(audio_out_queue, mp4_muxer);
>>
>>
>>       /* Set the pipeline stat to play and start the main loop*/
>>       g_print("Starting the pipeline\n");
>>       gst_element_set_state(pipeline, GST_STATE_PLAYING);
>>       g_main_loop_run(loop);
>>
>>       /* We are done now, do a little bit of cleaning up */
>>       g_print("Stopping the pipeline.\n");
>>       gst_element_set_state(pipeline, GST_STATE_NULL);
>>       gst_object_unref(GST_OBJECT(pipeline));
>>
>>       return 0;
>> }
>> _______________________________________________
>> gstreamer-devel mailing list
>> [hidden email]
>> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel